我喜欢做的事情大致如下:Javascript:关闭循环?
for(var i = 0; i < 10; ++i) {
createButton(x, y, function() { alert("button " + i + " pressed"); }
}
的这个是,我总是得到的i
终值,因为Javasript的关闭是没有价值的。
那么我怎样才能做到这一点与JavaScript?
我喜欢做的事情大致如下:Javascript:关闭循环?
for(var i = 0; i < 10; ++i) {
createButton(x, y, function() { alert("button " + i + " pressed"); }
}
的这个是,我总是得到的i
终值,因为Javasript的关闭是没有价值的。
那么我怎样才能做到这一点与JavaScript?
for(var i = 0; i < 10; i++) {
(function(i) {
createButton(function() { alert("button " + i + " pressed"); });
})(i);
}
注意的JSLint不喜欢这种模式。它会抛出“不要在循环中创建函数”。
因为它的清洁,我比Peter更喜欢这个答案。如果更多浏览器支持'let'关键字,那将会很好。 – McStretch 2011-04-05 17:13:20
@McStretch我试图在jsFiddle中做一个'let'演示,但是我无法让它工作。看到这里:http://jsfiddle.net/simevidas/ZKeXX/1/ Firefox 4会引发错误。 – 2011-04-05 17:31:03
@Šime - 我刚刚看到这个问题:http://stackoverflow.com/questions/2356830/what-browsers-currently-support-javascripts-let-keyword,它说你必须明确地告诉浏览器(Firefox现在只有现在)你使用的是1.7。这是一个更新的小提琴:http://jsfiddle.net/simevidas/ZKeXX/1/。很蹩脚吧?显然,直到每个人都支持1.7或更高版本,并且知道何时会发生,这不是一个很好的解决方案。 – McStretch 2011-04-05 17:52:54
您需要将闭包放入单独的函数中。
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);
}
for(var i = 0; i < 10; ++i) {
createButton(x, y, (function(n) {
return function() {
alert("button " + n + " pressed");
}
}(i));
}
在外面的匿名功能将自动调用并在其范围内,在那里,它利用每个i
的然后当前值创建具有n
一个新的闭合它被调用的时间。
通过执行另一个函数创建关闭一个新的范围:
for(var i = 0; i < 10; ++i) {
createButton(x,y, function(value) { return function() { alert(...); }; }(i));
}
1。您可能希望在return语句的末尾放置一个分号,以使代码更具可读性。 2. IIFE通常包裹在parens中。 – 2011-04-05 17:02:18
@Šime,是的,我同意。 – 2011-04-05 17:07:30
一个解决方案,如果你的编码为使用JavaScript 1.7或更高版本浏览器,是使用let
关键字:
for(var i = 0; i < 10; ++i) {
let index = i;
createButton(x, y, function() { alert("button " + index + " pressed"); }
}
从MDC文件中心:
let关键字导致项目 变量与块0一起创建级别作用域,导致为for循环的每次迭代 创建一个新的引用 。这意味着每个 闭包都会捕获一个单独的变量,从而解决共享环境造成的问题。
查看MDC Doc Center的传统方法(创建另一个闭包)。
您可以编辑createButton,允许它传递另一个参数,即i。这样你可以将我存储在你的createButton函数中并使用它。 – rsplak 2011-04-05 16:55:09
[Javascript闭包内循环 - 简单实用示例]的可能重复(http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – rds 2013-01-17 17:53:41