我喜欢在私有命名空间中编写回调函数,然后通过引用调用它们。例如
var myCallback = function() {
};
// ... somewhere else in the class.
SomeOtherObject.doSomething(myCallback);
这使得代码更整洁,更具扩展性。但是,当我需要将任何参数传递给原始函数的回调时,它变得很乱,我必须将回调引用括在闭包中。例如
var myCallback = function(a_var, another_var) {
};
// ... somewhere else in the class.
a_var = "something";
SomeOtherObject.doSomething(function(another_var) {
myCallback(a_var, another_var);
};
这导致回调需要两个函数调用而不是一个,从而产生开销。这也意味着我有一个未记录的匿名函数用于闭包 - 或者我记录了这两个函数。 (这不是缺少的函数定义,它作为参数定义很烦人。)如果回调很小 - 好的函数是 - 那么它就不值得把它作为私有范围。
这样做的最佳方式是什么?
答案 0 :(得分:2)
部分应用程序实现允许您以这种方式传递变量。
例如,使用原生ES5's bind
:
SomeOtherObject.doSomething( myCallback.bind(null, a_var) );
调用 时, 虽然它并不是所有地方都支持,所以你可以抓住一个from underscore并使用它。another_var
将传递给该函数
答案 1 :(得分:1)
你可以做功能currying。
Function.prototype.curry = function() {
if (arguments.length<1) {
return this;
}
var __method = this;
var slice = [].slice;
var args = slice.call(arguments);
return function() {
return __method.apply(this, args.concat(slice.call(arguments)));
}
}
然后
var a_var = "something";
SomeOtherObject.doSomething(myCallback.curry(a_var));
答案 2 :(得分:1)
你在谈论 curry'ing 。实际上,您可以使用ES5 Function.prototype.bind
来实现这一目标:
var myCallback = function(a_var, another_var) {
};
SomeOtherObject.doSomething(myCallback.bind(null, a_var, another_var);
当.bind()
获取参数并创建新函数并使用新范围和变量返回它时,会发生什么。可能传递给doSomething
的任何其他参数将出现在该绑定列表的末尾。
使用.bind()
时的警告是性能。由于某种原因(我到目前为止没有想到的)它的烦人慢。它在您的应用程序中并不重要,因为我们仍然在讨论每秒几十万次操作,但与普通函数相比,绑定函数调用减慢了大约60 -90%。