【发布时间】:2012-02-16 10:08:24
【问题描述】:
我遇到过它们,但我还不明白为什么要使用它们。谁能解释一下?
【问题讨论】:
标签: flash actionscript-3 function anonymous
我遇到过它们,但我还不明白为什么要使用它们。谁能解释一下?
【问题讨论】:
标签: flash actionscript-3 function anonymous
当你不需要为这个函数命名时,它很适合用在闭包中。 IE。这样:
var myFunc : Function = function() : void {trace("Hello world!");}
doSomething(myFunc);
或者这个:
button.addEventListener(MouseEvent.CLICK,
function(e : MouseEvent) : void
{
// doSomething
});
您不必使用它们,但如果更容易,您可以使用它们。
【讨论】:
button.removeEventListener(MouseEvent.CLICK, arguments.callee)
本质上,匿名函数允许您创建非常细粒度的行为变体,而无需创建子类,或者将原本必须是复杂的 switch 语句的内容封装到一个简短、干净的方法块中:将不得不根据状态做出很多决定,您现在可以简单地分配一个函数以在运行时执行特定任务。把它想象成任何变量——只有这种特殊类型的变量没有值,而是行为。
这方面的标准示例是事件侦听器,但您也可以将其应用于您想要的任何其他功能。
您可以了解匿名函数here,随后了解closures at Wikipedia 的概念。诚然,Wikipedia 资源中的技术术语有点重,但 Martin Fowler 也有一个关于这个主题的相当 readable blog post。
【讨论】:
冒着过于简单化的风险,您可以将匿名函数视为需要在运行时创建的“一次性”函数。以下是您可以在哪里使用的示例:
想象一下屏幕上有一些按钮用于更改颜色,每个按钮的处理程序如下所示(伪代码,请忽略语法错误):
private function redBtnHandler(): void {
GlobalBrush.setColor(0xff0000);
}
private function greenBtnHandler(): void {
GlobalBrush.setColor(0x00ff00);
}
private function blueBtnHandler(): void {
GlobalBrush.setColor(0x0000ff);
}
...
redBtn.setClickHandler(redBtnHandler);
greenBtn.setClickHandler(greenBtnHandler);
blueBtn.setClickHandler(blueBtnHandler);
...
创建一堆这样的东西很痛苦,更不用说以后很难编辑了。
相反,您可以使用“函数工厂”来生成处理程序,如下所示:
private function generateBtnHandler(rgb:uint): Function {
var btnHandler:Function = function(): void {
GlobalBrush.setColor(rgb);
}
return btnHandler;
}
redBtn.setClickHandler(generateBtnHandler(0xff0000));
greenBtn.setClickHandler(generateBtnHandler(0x00ff00));
blueBtn.setClickHandler(generateBtnHandler(0x0000ff));
在上述“一劳永逸”的情况下,这些非常方便。
希望以上示例有助于阐明为什么有人会使用这些东西。
【讨论】:
http://www.adobe.com/devnet/actionscript/learning/as3-fundamentals/functions.html
http://www.alanmacdougall.com/blog/post/3/
或者
匿名函数的定义如下:
bar = function(param1, param2, etc) {
// do stuff here
}
匿名函数是有趣的野兽。与命名函数不同,当您创建匿名函数时,无法通过代码引用该函数。我们可以通过函数字面量来解决这个问题。
创建函数时,它会返回对自身的引用。在上面的示例中,我们设置了一个变量“bar”来引用我们创建的匿名函数。
现在,每当调用 bar 时,它引用的匿名函数都会执行。与命名函数不同,匿名函数不能被前向引用。如果我在设置 bar 引用该函数之前调用 bar,调用将失败。
创建匿名递归函数时,该函数可以通过使用 arguments.callee 属性来引用自身。考虑这个例子:
// classic factorial recursion example
factorial = function(n) {
if (n <= 1) {
return n;
} else {
return n*arguments.callee(n-1); // call ourself to recurse
}
}
请注意,在上面的示例中,我们可以将 arguments.callee 替换为阶乘,并且该示例仍然有效。但是,有时我们没有变量来调用函数。在这些情况下,arguments.callee 是唯一的解决方案。这方面的一个例子可能是将匿名函数作为参数传递给另一个函数。
函数字面量可以在任何时间线/对象中定义函数,前提是定义时路径存在。例如,要在对象内部创建函数,我们必须使用这样的函数字面量:
obj = new Object();
obj.foo = function() {
return "bar";
}
trace(obj.foo()); // bar
【讨论】: