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之外可以缓解臭名昭着的循环问题,不是吗?
答案 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])创建一个代理,其link
为this
上下文,i
为{{1}的默认参数}}
要使您的示例正常工作,您需要执行此操作:
Outside
答案 2 :(得分:2)
你写的代码不会运行我相信。
外面不会返回任何东西。所以调用Outside(i)将返回undefined。这意味着你要设置link.onclick = undefined。