javascript更高阶函数; “this”参数vs外部“self”变量

时间:2012-10-22 08:28:41

标签: javascript

在javascript中使用Array API的高阶函数时(forEach,map,filter等) 有两种方法可以传递“this”变量:

myArray.forEach(function(value) {
    this.aContextualFunction();
}, this);

或者

var self = this;
myArray.forEach(function(value) {
    self.aContextualFunction();
});

哪一个更好? 有什么优点和缺点?

示例:http://jsfiddle.net/TkZgX/

2 个答案:

答案 0 :(得分:3)

我总是喜欢第一个。

亲:没有额外的var声明

con:也许在这个问题的评论中看到了混淆..

答案 1 :(得分:2)

当使用高阶函数时,我更喜欢我的函数,不要对它作为参数接收的回调做出任何假设。一般来说,代码越松散耦合越好。

例如,假设我为forEach写了一个更高阶的函数:

function forEach(array, callback, that) { // that is optional
    var length = array.length;
    for (var i = 0; i < length; i++)
        callback.call(that, array[i], i); // pass the value and the index
}

现在说我想用它:

Array.prototype.double = function () {
    forEach(this, function (value, index) {
        this[index] = 2 * value;
    });                                     // oops, I forgot that
};

var array = [1, 2, 3];
array.double();

上述代码将导致变量泄漏到全局范围。不是一件好事。请参阅此处的演示:http://jsfiddle.net/8dad4/

有什么替代方案?删除可选的第三个参数并使用闭包:

function forEach(array, callback) {
    var length = array.length;
    for (var i = 0; i < length; i++)
        callback(array[i], i);
}

不仅代码更小,而且不会发生任何意外的全局泄漏(除非您使用this而不是外部that像白痴一样)。我们来看一个例子:

Array.prototype.double = function () {
    var that = this;

    forEach(this, function (value, index) {
        that[index] = 2 * value;
    });
};

var array = [1, 2, 3];
array.double();

演示在这里:http://jsfiddle.net/8dad4/1/

嗯......这似乎不太诱人 - 我不想创建一个新的变量。我们可以做些更好的事吗?是的,我们当然可以。这是我喜欢的方法(我们仍然使用第二个forEach函数):

Array.prototype.double = function () {
    forEach(this, function (value, index) {
        this[index] = 2 * value;
    }.bind(this));
};

var array = [1, 2, 3];
array.double();

演示在这里:http://jsfiddle.net/8dad4/2/

哇,这不是更好吗?我们将方法一和二结合起来。优点:

  1. forEach函数不承担任何责任。代码更松散耦合。
  2. 我们不需要像that这样的外部变量。不需要关闭。
  3. 对于发生的事情没有混淆。
  4. 我们可以这样做,因为传递给forEach的匿名函数是一个函数表达式。所以我们只需将.bind(this)附加到其中即可。