gpt4 book ai didi

Javascript臭名昭著的循环问题?

转载 作者:IT老高 更新时间:2023-10-28 13:13:48 24 4
gpt4 key购买 nike

我有以下代码片段。

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

以上代码用于生成 5 个链接并将每个链接与警报事件绑定(bind)以显示当前链接 ID。但它不起作用。当您单击生成的链接时,它们都会显示“链接 5”。

但下面的代码片段符合我们的预期。

function addLinks () {
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);
}
}

以上两段摘自here .正如作者的解释,似乎 闭包 具有魔力。

但它是如何工作的,以及 closure 如何使它工作,这一切都超出了我的理解。为什么第一个不起作用,而第二个起作用?谁能详细解释一下魔法?

最佳答案

Quoting myself关于第一个例子的解释:

JavaScript's scopes are function-level, not block-level, and creating a closure just means that the enclosing scope gets added to the lexical environment of the enclosed function.

After the loop terminates, the function-level variable i has the value 5, and that's what the inner function 'sees'.

在第二个示例中,对于每个迭代步骤,外部函数字面量将评估为具有自己的范围和局部变量 num 的新函数对象。 ,其值设置为 i 的当前值.如num永远不会被修改,它将在闭包的生命周期内保持不变:下一个迭代步骤不会覆盖旧值,因为函数对象是独立的。

请记住,这种方法效率很低,因为必须为每个链接创建两个新的函数对象。这是不必要的,因为如果您使用 DOM 节点进行信息存储,它们可以很容易地共享:

function linkListener() {
alert(this.i);
}

function addLinks () {
for(var i = 0; i < 5; ++i) {
var link = document.createElement('a');
link.appendChild(document.createTextNode('Link ' + i));
link.i = i;
link.onclick = linkListener;
document.body.appendChild(link);
}
}

关于Javascript臭名昭著的循环问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1451009/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com