0
for (var i=0, link; i<5; i++) {
    link = document.createElement("a");
    link.innerHTML = "Link " + i;
    link.onclick = function (num) {
        return function () {
            alert(num);
        };
    }(i);
    document.body.appendChild(link);
}

由于嵌套函数是一个闭包,它有一个对num参数的引用num,循环结束时的参数是 4 。现在当第一个元素被点击时,为什么它会提示 1 ?它应该提示 4 。提示的原因是什么1 ?不要它引用num论点?或者是什么原因?

但这里的情况不同:

function foo(x) {
    var tmp = 3;
    return function (y) {
       alert(x + y + (++tmp));
    }
}
var bar = foo(2); // bar is now a closure.
bar(10);

上面的函数将警告 16,因为 bar 仍然可以引用 argxtmp,即使它不再直接位于范围内。

这证明了闭包也引用了参数值,而不是为什么上面的代码每次都没有提醒 4?

4

2 回答 2

3
  for (var i=0, link; i<5; i++) {  //i starts at 0 and iterates up to 4
        link = document.createElement("a");
        link.innerHTML = "Link " + i;


         link.onclick = function (num) {
            //num is never changed within this function, and is equal
            //to the value of i when it was passed in

            return function () { alert(num);};

        }(i);  //i is passed here
        //that sets num to the current value of i for each link

        document.body.appendChild(link);
   }

对于第一个链接,num 将为 0,因为i它在传递给外部函数时是 1。然后 i 为循环的每一轮迭代,并且对于每个链接将是不同的值。

这里的模式是一种非常常见的模式,用于在回调/事件绑定中保留循环迭代的当前值。

于 2013-04-03T17:54:00.703 回答
0

您正在做的是避免单击第一个元素会给您 4 而不是 1 的经典示例,这应该是最期望的值。

如果您希望它提醒 1,那么只需执行以下操作:

link.onclick = function() {alert(i);};

但老实说,这有什么意义呢?所有 4 个链接都会提醒 4...

于 2013-04-03T17:56:09.693 回答