0

我想在 for 循环中向 li 添加事件。

我知道什么总是出错:i闭包可以访问的是i. i需要锁定在封闭中。

要解决这个问题,请使用立即调用函数表达式。

我不明白为什么这不起作用!

for (var i = 0; i < 10; i++){
    var li = document.createElement('li');
    ul.appendChild(li);
    li.onclick = (function(i2){
        return slideTo(i2);    // slideTo is a global function
    }(i));

但我知道这会奏效:

li.onclick = (function(i2){
    return function(){ 
        slideTo(i2);        // slideTo is a global function
    }
}(i));

为什么我需要放入slideTo(i)匿名函数???

这两个表达有什么区别??

十分感谢!!!

4

2 回答 2

0

在第一种情况下,您只是将值分配slideTo(i2)onclick

li.onclick = (function(i2){
    // Here, "i2" is **immediately** used to invoke
    // slideTo(i2). It is invoked right here, in 
    // every loop iteration. 
    return slideTo(i2);
}(i));

以上将在每次循环迭代中进行评估,因此它相当于:

li.onclick = slideTo(i);

在合同中,在第二个示例中,您创建了一个适当的闭包,从而将一个函数(不是第一个场景中的li.onclick)分配给侦听器:

li.onclick = (function(i2){
    // Here, "i2" is in a scope, but it's **not immediately** used.
    // Instead, you are returning function which will be assigned
    // to "li.onclick" but with THIS scope (i.e. scope with
    // "i2" value).
    //
    // New scope is created in every loop iteration, but the following
    // function **is not called** in a loop.
    return function() {
         // Later, when <li> is clicked, slideTo(i2) will be called.
         slideTo(i2);
    }
}(i));
于 2013-10-18T06:44:01.300 回答
0

第二种形式需要创建一个的变量绑定(即i2) - 第一种形式会立即评估(它不返回执行后面工作的函数对象),因此不是“回调”。

请记住,只有新的函数作用域会创建新的变量。如果没有双闭包,您将引用相同 i的变量。另一种方法是使用Function.bind(它本身可以用闭包来模拟)。

于 2013-10-18T06:44:03.793 回答