5

在 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/

4

2 回答 2

3

我总是喜欢第一个。

亲:没有额外的 var 声明

缺点:可能是在这个问题的评论中看到的混乱..

于 2012-10-22T08:47:28.100 回答
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. 对于正在发生的事情没有任何困惑。

我们可以这样做,因为传递给的匿名函数forEach是一个函数表达式。所以我们只是追加.bind(this)它,我们就完成了。

于 2012-10-22T10:29:29.450 回答