Javascript Ninja:数组中的当前元素作为函数上下文

时间:2015-01-19 09:59:29

标签: javascript function call

我正试图在第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函数。我不确定会导致什么麻烦,如果有的话,可能与更改函数上下文的原因有关。

1 个答案:

答案 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,那么这只会造成麻烦。改变它的原因就是我上面解释的。