我想做以下事情:
for (var i = 0; i < 10; ++i) {
createButton(x, y, function() { alert("button " + i + " pressed"); }
}
这个问题是我总是得到i
的最终值,因为Javascript的闭包不是按值。
那么我怎么能用javascript做到这一点?
答案 0 :(得分:7)
如果您要编写使用JavaScript 1.7或更高版本的浏览器,则可以使用let
关键字来解决一个问题:
for(var i = 0; i < 10; ++i) {
let index = i;
createButton(x, y, function() { alert("button " + index + " pressed"); }
}
来自MDC文档中心:
let关键字会导致该项目 用块创建的变量 级别范围,导致新的引用 为每次迭代创建 for循环。这意味着一个 为每个捕获单独的变量 关闭,解决由此引起的问题 共享环境。
查看传统方法的MDC Doc Center(创建另一个闭包)。
答案 1 :(得分:6)
for(var i = 0; i < 10; i++) {
(function(i) {
createButton(function() { alert("button " + i + " pressed"); });
})(i);
}
请注意,JSLint不喜欢这种模式。它抛出“不要在循环中创建函数。”。
答案 2 :(得分:4)
通过执行另一个函数为闭包创建一个新的作用域:
for(var i = 0; i < 10; ++i) {
createButton(x,y, function(value) { return function() { alert(...); }; }(i));
}
答案 3 :(得分:1)
您需要将闭包放入单独的函数中。
for(var dontUse = 0; dontUse < 10; ++dontUse) {
(function(i) {
createButton(x, y, function() { alert("button " + i + " pressed"); }
})(dontUse);
}
Thise代码创建一个匿名函数,该函数将i
作为循环每次迭代的参数。
由于此匿名函数对每次迭代都有一个单独的i
参数,因此它解决了问题。
这相当于
function createIndexedButton(i) {
createButton(x, y, function() { alert("button " + i + " pressed"); }
}
for(var i = 0; i < 10; ++i) {
createIndexedButton(i);
}
答案 4 :(得分:0)
for(var i = 0; i < 10; ++i) {
createButton(x, y, (function(n) {
return function() {
alert("button " + n + " pressed");
}
}(i));
}
外部的匿名函数会自动调用,并在其范围内创建一个n
的新闭包,每当它出现{em>然后当前值为i
时调用