使用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/
哇,这不是更好吗?我们将这两种方法结合在一起。优点:
-
forEach
功能不假定任何事情。代码更加松散。 - 我们不需要诸如
that
之类的外部变量。无需封闭。 - 对正在发生的事情没有混乱。
我们可以这样做,因为传递给forEach
的匿名函数是函数表达式。因此,我们只是将.bind(this)
附加到它。