首先,我的理解是,某些语法javascript和actionscript的appart以非常类似的方式运行。在两种语言中,我都需要将局部变量添加到某种事件监听器中。例如在actionscript中:
public class Foo {
public function handleBar():void {
this.bla(); this.blabla();
}
public function createButton():void {
SomeSortOfButton button = new SomeSortOfButton();
//HERE COMES THE AWKWARD PART:
button.addEventListener(MouseEvent.CLICK,
(function (foo:Foo) {
return function (event:MouseEvent):void {
//I want to do stuff with foo, hence the function that returns a function.
foo.handleBar();
};
})(this)
);
}
}
在javascript(+ jquery)中我不时有这样的事情:
var foo = ......;
$("#button").click(
(function(bar) {
return function(event) {
//do stuff with bar (which is defined as foo in the first line)
};
)(foo)
);
我喜欢它的工作方式,但就语法而言,它是一个完整的 no go imho。还有其他选择吗?我在actionscript中尝试的是在处理程序中使用默认参数:
public class Foo {
public function handleBar():void {
this.bla(); this.blabla();
}
public function createButton():void {
SomeSortOfButton button = new SomeSortOfButton();
//HERE COMES THE ALTERNATIVE:
button.addEventListener(MouseEvent.CLICK,
function (event:MouseEvent, foo:Foo = this):void {
//I want to do stuff with foo, hence the function that returns a function.
foo.handleBar();
}
);
}
}
但是这是不允许的,因为 foo中的 this :Foo = this 在编译时无法解析。很公平,但我仍然想知道,在javascript和actionscript中是否存在上述构造的语法糖?我更喜欢使用单个函数,而不是返回函数的函数。
我希望答案的形式为:“(据我所知),传递局部变量没有其他办法”或“是的,你可以这样做:....“。
但当然,非常感谢任何评论!
答案 0 :(得分:1)
这是需要"curry" function的经典示例。 Prototype库有一个,但也很容易推出自己的:
function curry(func) {
var args = Array.prototype.slice.call(arguments, 1);
return function() {
return func.apply(this, Array.prototype.concat.apply(args, arguments));
};
}
然后在你的JavaScript示例中:
var foo = ......;
$("#button").click(curry(function(bar, event) {
//do stuff with bar (which has the value of `foo` as of when we hooked up the handler)
}, foo));
ES5有Function#bind
,用于在函数中设置this
值,但也可用于curry。但是如果你使用Function#bind
,就不能让this
通过(这就是上面curry
所做的事情:它用任何this
值来调用函数被称为,而不是特定的。)
这是一般情况。在jQuery事件处理程序的特定情况下,jQuery为您提供了一种方法:
var foo = ......;
$("#button").click({bar: foo}, function(event) {
//do stuff, using event.data.bar
});