在编程中,闭包在从外部作用域捕获变量方面发挥着至关重要的作用。然而,当在循环中使用时,它们可能会导致意想不到的结果,称为闭包污染。本文探讨了这个问题并提供了解决它的实用解决方案。
考虑以下代码:
<code class="javascript">var funcs = []; for (var i = 0; i < 3; i++) { funcs[i] = function() { console.log("My value:", i); }; } for (var j = 0; j < 3; j++) { funcs[j](); }</code>
不幸的是,此代码输出:
<code>My value: 3 My value: 3 My value: 3</code>
而不是:
<code>My value: 0 My value: 1 My value: 2</code>
问题的出现是因为循环中声明的每个函数都从外部作用域捕获相同的 i
变量。当函数在第二个循环中被调用时,它们都引用相同的 i
,在执行时它已增加到 3。
let
ES6 引入了 let
关键字,它创建块作用域变量。在循环中使用 let
确保每次迭代都有自己不同的 i
变量,解决闭包污染问题:
<code class="javascript">for (let i = 0; i < 3; i++) { funcs[i] = function() { console.log("My value:", i); }; }</code>
forEach
另一个数组的解决方案是使用 forEach
方法:
<code class="javascript">var someArray = [/* values */]; someArray.forEach(function(element) { // ...code specific to this element... });</code>
forEach
循环的每次迭代都会创建自己的闭包,捕获特定于该迭代的数组元素。
经典的解决方案涉及手动将变量绑定到函数外部一个单独的、不变的值:
<code class="javascript">var funcs = []; function createFunc(i) { return function() { console.log("My value:", i); }; } for (var i = 0; i < 3; i++) { funcs[i] = createFunc(i); } for (var j = 0; j < 3; j++) { funcs[j](); }</code>
通过将 i
变量作为参数传递给内部函数函数时,我们为每次迭代创建一个新的闭包,确保每个函数引用其自己的独立值。
以上是如何克服循环中的封闭污染:实用指南的详细内容。更多信息请关注PHP中文网其他相关文章!