Javascript臭名昭着的循环问题? [英] Javascript infamous Loop issue?

查看:122
本文介绍了Javascript臭名昭着的循环问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码段。

  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个链接,链接到一个警报事件以显示当前链接ID。但它不工作。当你点击生成的链接,他们都说链接5。



但以下代码段可作为我们的期望。

  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个片段来自此处



但是它是如何工作的,以及 closure 是如何实现的工作都超出了我的理解。为什么第一个不工作,而第二个工作?任何人都可以详细解释魔法吗?



感谢。

解决方案

自我介绍第一个示例的说明:


JavaScript的范围是函数级的,而不是块级的,创建闭包只是意味着封闭范围被添加到封闭函数的词法环境中。



循环结束后,函数级变量i的值为5,这是内部函数看到的。


在第二个例子中,对于每个迭代步骤,外部函数文字将计算一个具有自己作用域和局部变量的新的函数对象 num ,其值设置为 i 的当前值。由于 num 从不修改,它将在闭包的整个生命周期内保持不变:下一个迭代步骤不会覆盖旧值,因为函数对象是独立的。请记住,这种方法是相当低效的,因为必须为每个链接创建两个新的函数对象。p>

这是不必要的,因为如果你使用DOM节点来存储信息,他们可以很容易地共享:

  function linkListener b $ b alert(this.i); 
}

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


I've got the following code snippet.

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);
    }
}

The above code is for generating 5 links and bind each link with an alert event to show the current link id. But It doesn't work. When you click the generated links they all say "link 5".

But the following codes snippet works as our expectation.

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);
    }
}

The above 2 snippets are quoted from here. As the author's explanation, seems the closure makes the magic.

But how it works and How closure makes it work are all beyond my understanding. Why the first one doesn't work while the second one works? Can anyone give a detailed explanation about the magic?

thanks.

解决方案

Quoting myself for an explanation of the first example:

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'.

In the second example, for each iteration step the outer function literal will evaluate to a new function object with its own scope and local variable num, whose value is set to the current value of i. As num is never modified, it will stay constant over the lifetime of the closure: The next iteration step doesn't overwrite the old value as the function objects are independant.

Keep in mind that this approach is rather inefficient as two new function objects have to be created for each link. This is unnecessary, as they can easily be shared if you use the DOM node for information storage:

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臭名昭着的循环问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆