我正试图在第57页的Javascript忍者中包围一些代码。
function forEach(list, callback) {
for (var n = 0; n < list.length; n++) {
callback.call(list[n], n); //makes the current element the function context of callback???
}
}
var weapons = ['shuriken', 'katana', 'nunchucks'];
forEach(weapons,
function(index) {
assert(this == weapons[index], "Got the expected value of " + weapons[index]);
}
);
我可以在不使用call方法的情况下传递回调中数组的索引,这是有道理的。我不明白的是为什么我要将当前元素用作函数上下文。这是想要完成什么?
我也很难理解如何做到这一点。我假设调用方法将列表项视为对象而不是数组中的元素。但我不确定这是否正确。
我的另一个想法是,通过不将函数上下文分配给当前元素,函数上下文将是forEach
函数。我不确定会导致什么麻烦,如果有的话,可能与更改函数上下文的原因有关。
答案 0 :(得分:2)
我不明白为什么我要将当前元素用作函数上下文。
这允许您执行的操作是在回调函数中使用this
来引用每个相应的当前元素。这与jQuery $.each()
方法和其他一些jQuery方法使用的约定相同(本书的作者是jQuery的创建者)。
它允许你这样做:
forEach([1, 2, 3], function() {
console.log(this * 2); // 'this' refers to the current element
});
输出:
2
4
6
当然,另一种非常精细的方法是将当前元素作为参数传入,而不是指定函数上下文。这就是内置Array.prototype.forEach
(基本上)所做的。该方法的简化版本如下所示:
function forEach(list, callback) {
for (var i = 0; i < list.length; i++) {
callback(list[i], i);
}
}
forEach([1, 2, 3], function(item) {
console.log(item * 2); // 'item' is the current element
});
这两种方法都没有明显好于另一种方法。只是有些人发现能够使用this
更方便。
我也很难理解如何做到这一点。我假设调用方法将列表项看作对象而不是数组中的元素。但我不确定这是否正确。
传递给call()
的函数上下文可以是任何东西。它只是确定函数执行时this
所占的值(大多数时间)。
我的另一个想法是,通过不将函数上下文分配给当前元素,函数上下文将是forEach函数。
不,如果此处未指定函数上下文,则在严格模式下为null
,在quirks模式下为window
(假设代码在浏览器中运行)。这两点都不会特别有用。
我不确定会导致什么麻烦,如果有的话,可能与改变功能背景的原因有关。
如果有人试图以任何有意义的方式在回调中使用this
,那么这只会造成麻烦。改变它的原因就是我上面解释的。