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 仍然可以引用 arg x
和 tmp
,即使它不再直接在范围内。
这证明闭包也有对参数值的引用,而不是为什么上面的代码每次都不提醒 4?
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
在传递给外部函数时是一个。 然后,i 针对循环的每一轮进行迭代,并且对于每个链接将是一个不同的值。
这里的模式是一种非常常见的模式,用于在回调/事件绑定中保留循环迭代的当前值。
您正在做的是避免单击第一个元素会给您 4 而不是 1 的经典示例,这应该是最期望的值。
如果您希望它发出警报 1,则只需执行以下操作:
link.onclick = function() {alert(i);};
但老实说,这有什么意义呢?所有 4 个链接都会提醒 4...