0

我喜欢在私有命名空间中编写回调函数,然后通过引用调用它们。例如

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);
};

这导致回调需要两个函数调用而不是一个,从而产生开销。这也意味着我有一个未记录的闭包匿名函数 - 或者我记录了这两个函数。(与其说是缺少的函数定义不如参数定义那么烦人。)如果回调很小——就像好的函数一样——那么把它放在私有范围内似乎不值得。

做这个的最好方式是什么?

4

3 回答 3

2

部分应用程序实现允许您以这种方式传递变量。

例如,使用原生ES5 的bind

SomeOtherObject.doSomething( myCallback.bind(null, a_var) );

another_var调用时将传递给该函数

但是,它并非在所有地方都受支持,因此您可以从下划线中获取并使用它。

于 2012-08-30T07:45:34.373 回答
1

你可以做函数柯里化。

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));
于 2012-08-30T07:45:36.127 回答
1

你在谈论curry'ing。实际上,你可以Function.prototype.bind像这样使用 ES5 来完成:

var myCallback = function(a_var, another_var) {
};

SomeOtherObject.doSomething(myCallback.bind(null, a_var, another_var);

那里发生的事情是.bind()接受参数并创建一个新函数并返回它,并带有新的范围和变量。然后,可能传递给的任何其他参数都doSomething将出现在该绑定列表的末尾。

使用的警告.bind()是性能。出于某种原因(到目前为止我还没有想到)它令人讨厌的缓慢。这在您的应用程序中并不重要,因为我们仍在谈论每秒数十万次操作,但与普通函数相比,绑定函数调用会减慢大约 60-90%。

于 2012-08-30T07:45:41.510 回答