gpt4 book ai didi

Javascript 臭名昭著的循环问题?

转载 作者:行者123 更新时间:2023-11-28 04:40:51 25 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);
}
}

以上2段摘自here 。正如作者的解释所示,似乎闭包创造了魔力。

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

最佳答案

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 的新函数对象,其值设置为 的当前值>我。由于 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/43793883/

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