JavaScript高阶函数; "this"参数与外部"self"变量



使用JavaScript中数组API的高阶功能时(foreach,map,filter等)有两种通过"此"变量的方法:

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

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

哪一个更好?什么是利弊?

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

我总是更喜欢第一个。

pro:无额外的var声明

con:也许在此问题的评论中看到的混乱。

使用高阶功能时,我更喜欢我的功能不要对其作为参数收到的回调做出任何假设。通常,越松散耦合代码越好。

例如,说我为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/

hmmm ...这似乎不是很诱人 - 我不想创建一个新变量。我们可以做得更好吗?是的,我们肯定可以。这是我喜欢的方法(我们仍然使用第二个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)附加到它。

最新更新