臭名昭着的循环机会

时间:2013-03-27 20:42:33

标签: javascript

This page谈论臭名昭着的循环问题:

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);
    }
}
window.onload = addLinks;

一个解决方案:

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);
    }
}
window.onload = addLinks;

这是我的问题:如果您调用的函数在父函数之外(例如,在addLinks之外),臭名昭着的循环问题是否仍然存在问题?

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

我认为这是因为问题的产生是因为当onclick作为一个函数被调用时,还没有创建addLinks。因此,将函数放在addLInks之外可以缓解臭名昭着的循环问题,不是吗?

3 个答案:

答案 0 :(得分:4)

代码中的问题是它不起作用。

link.onclick = Outside(i);

不绑定函数,因为Outside(i)返回undefined。

类似的,有效的解决方案是将Outside定义为

function Outside(i) {
    return function() {
       alert(i);
    }
};

它可以用于第二个代码的相同原因:调用函数Outside为变量i创建一个新的范围(它被称为闭包)。

您从循环中构建的任何解决方案可能不仅仅涉及函数调用:它需要声明变量,使用var关键字或作为该函数的参数。< / p>

答案 1 :(得分:2)

link.onclick = Outside(i);

这实际上会调用Outside(i),而不是将侦听器设置为等于具有该默认值的该函数。像Ext这样的各种工具包提供了一种创建类似于devtroy所显示的委托的方法。例如,在Ext 3.X中你可以这样做:

link.onclick = Outside.createDelegate(link,[i])创建一个代理,其linkthis上下文,i为{{1}的默认参数}}

要使您的示例正常工作,您需要执行此操作:

Outside

答案 2 :(得分:2)

你写的代码不会运行我相信。

外面不会返回任何东西。所以调用Outside(i)将返回undefined。这意味着你要设置link.onclick = undefined。