我对这段代码感到非常困惑:
var closures = [];
function create() {
for (var i = 0; i < 5; i++) {
closures[i] = function() {
alert("i = " + i);
};
}
}
function run() {
for (var i = 0; i < 5; i++) {
closures[i]();
}
}
create();
run();根据我的理解,它应该输出0,1,2,3,4 (这不就是闭包的概念吗?)。
相反,它会打印5,5,5,5,5。
我试过Rhino和Firefox。有人能给我解释一下这种行为吗?
发布于 2009-03-13 16:57:48
通过添加额外的匿名函数修复了Jon的答案:
function create() {
for (var i = 0; i < 5; i++) {
closures[i] = (function(tmp) {
return function() {
alert("i = " + tmp);
};
})(i);
}
}解释是JavaScript的作用域是函数级的,而不是块级的,创建闭包只是意味着将封闭的作用域添加到封闭函数的词法环境中。
循环结束后,函数级变量i的值为5,这就是内部函数“看到”的。
附注:您应该注意创建不必要的函数对象,特别是在循环中;它的效率很低,如果涉及DOM对象,则很容易创建循环引用,从而在Internet Explorer中引入内存泄漏。
发布于 2009-03-13 16:39:44
我想这可能是你想要的:
var closures = [];
function createClosure(i) {
closures[i] = function() {
alert("i = " + i);
};
}
function create() {
for (var i = 0; i < 5; i++) {
createClosure(i);
}
}发布于 2009-03-13 16:42:50
解决方案是让一个自动执行的lambda包装您的数组推送。您还可以将i作为参数传递给lambda。在自执行的lambda中,i的值将隐藏原始i的值,一切都将按预期运行:
function create() {
for (var i = 0; i < 5; i++) (function(i) {
closures[i] = function() {
alert("i = " + i);
};
})(i);
}另一种解决方案是创建另一个闭包,该闭包捕获i的正确值,并将其赋给另一个变量,该变量将在最终的lambda中“被捕获”:
function create() {
for (var i = 0; i < 5; i++) (function() {
var x = i;
closures.push(function() {
alert("i = " + x);
});
})();
}https://stackoverflow.com/questions/643542
复制相似问题