循环内的 JavaScript 闭包:了解问题及其解决方案
在使用 var 关键字进行变量声明的循环内使用闭包时会出现此问题。闭包捕获它们定义的环境(包括变量),并创建对它们的引用,即使在函数退出后也是如此。当捕获的变量在循环执行期间更改值时,这可能会导致意外行为。
问题:
考虑以下代码:
<code>for (var i = 0; i < 3; i++) { funcs[i] = function() { console.log("My value:", i); }; }</code>
这段代码创建了一个迭代三次的循环。在每次迭代中,都会定义一个函数并将其存储在数组中。预期输出将是:
<code>My value: 0 My value: 1 My value: 2</code>
但是,实际输出是:
<code>My value: 3 My value: 3 My value: 3</code>
这是因为变量 i 被闭包捕获,并且它被更新为最终的在执行任何闭包之前值为 3。
ES6 解决方案:使用 'let' 关键字
ECMAScript 6 (ES6) 引入了 let 关键字,它创建块-作用域变量。在我们的示例中,我们可以使用 let 而不是 var 为每次迭代创建一个新变量 i:
<code>for (let i = 0; i < 3; i++) { funcs[i] = function() { console.log("My value:", i); }; }</code>
这一次,每个闭包将捕获自己不同的 i 变量,并且将获得预期的输出.
ES5.1 解决方案:使用 'forEach'
JavaScript 的 Array.prototype.forEach 方法提供了一种迭代数组的简洁方法。传递给 forEach 的每个回调函数都会在当前元素周围获得一个不同的闭包:
<code>var someArray = [ /* whatever */ ]; someArray.forEach(function(element) { // Code specific to this element });</code>
经典解决方案:使用闭包
闭包可用于将变量绑定到函数外的特定值:
<code>function createfunc(i) { return function() { console.log("My value:", i); }; } var funcs = []; for (var i = 0; i < 3; i++) { funcs[i] = createfunc(i); }</code>
这里,使用 createfunc 创建一个特定于 i 的闭包,然后将其存储在 funcs 数组中。当执行每个闭包时,它们都会引用相应的 i 变量,从而产生正确的输出。
以上是如何解决 JavaScript 循环中闭包变量引用的问题?的详细内容。更多信息请关注PHP中文网其他相关文章!