如何在不嵌套的情况下分配回调参数

时间:2012-08-30 07:39:44

标签: javascript

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

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

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

这样做的最佳方式是什么?

3 个答案:

答案 0 :(得分:2)

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

例如,使用原生ES5's bind

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

时,

another_var将传递给该函数

虽然它并不是所有地方都支持,所以你可以抓住一个from underscore并使用它。

答案 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%。