JavaScript 循环中的闭包:简单实用示例
JavaScript 循环中的闭包:简单实用示例
技术背景
在 JavaScript 中,循环内使用闭包时会遇到一些问题。这是因为在 JavaScript 里,变量作用域基于函数,而非像 C# 那样有块级作用域。在循环里创建的闭包会引用同一个变量,导致最终所有闭包都使用该变量的最终值。
实现步骤
ES6 解决方案:let
ES6 引入了 let
和 const
关键字,它们的作用域与 var
不同。在使用 let
作为循环索引时,每次循环都会创建一个新的变量 i
,并具有块级作用域。示例代码如下:
1 |
|
不过要注意,IE9 - IE11 和 Edge 14 之前的版本虽然支持 let
,但在上述场景中处理有误,它们不会每次都创建新的 i
,所有函数都会输出 3,就像使用 var
一样。Edge 14 及之后版本才正确处理。
ES5.1 解决方案:forEach
Array.prototype.forEach
函数在 2015 年已广泛可用。当主要对数组值进行迭代时,.forEach()
能为每次迭代提供清晰、自然的方式来创建不同的闭包。示例如下:
1 |
|
如果使用 jQuery,$.each()
函数也有类似功能。
经典解决方案:闭包
可以将每个函数内的变量绑定到函数外部一个不变的值。示例代码如下:
1 |
|
也可以使用立即执行函数表达式(IIFE):
1 |
|
使用 Function.prototype.bind
1 |
|
为了提高性能,可以先在循环外创建函数,再在循环内绑定结果:
1 |
|
最佳实践
- 若项目支持 ES6,优先使用
let
关键字,代码简洁且易于理解。 - 当处理数组迭代时,可使用
forEach
方法,避免手动管理索引变量。 - 在不支持 ES6 的环境中,使用闭包或
Function.prototype.bind
来解决问题。
常见问题
所有闭包都输出相同值
这是因为闭包引用了同一个变量。可以使用上述解决方案,如 let
、闭包、forEach
或 Function.prototype.bind
来解决。
浏览器兼容性问题
部分旧浏览器(如 IE9 - IE11 和 Edge 14 之前的版本)对 let
支持有问题。在需要兼容这些浏览器时,可采用 ES5 的解决方案。
JavaScript 循环中的闭包:简单实用示例
https://119291.xyz/posts/2025-05-09.javascript-closure-inside-loops-example/