在javascript中使用Array API的高阶函数时(forEach,map,filter等) 有两种方法可以传递“this”变量:
myArray.forEach(function(value) {
this.aContextualFunction();
}, this);
或者
var self = this;
myArray.forEach(function(value) {
self.aContextualFunction();
});
哪一个更好? 有什么优点和缺点?
答案 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/
哇,这不是更好吗?我们将方法一和二结合起来。优点:forEach
函数不承担任何责任。代码更松散耦合。that
这样的外部变量。不需要关闭。我们可以这样做,因为传递给forEach
的匿名函数是一个函数表达式。所以我们只需将.bind(this)
附加到其中即可。