javascript 闭包通过保留对定义时词法作用域的引用来捕获外部变量,而非复制其值。具体做法是让内部函数引用外部函数的局部变量,并在外部函数执行后返回该内部函数,从而在内存中维持对该变量的访问权限。

为什么闭包能捕获变量而不是值
闭包捕获的是变量的引用,这意味着每次访问都读取当前内存中的最新值。如果外部变量是基本类型,修改它会影响所有引用的闭包;如果是对象,修改其属性同样会被捕获。

function createCounter() {
let count = 0;
return function() {
count++;
console.log(count);
};
}
const counter = createCounter();
counter(); // 输出: 1
counter(); // 输出: 2循环中闭包的常见陷阱
在 for 循环中使用 var 声明的变量会被所有闭包共享同一个引用,导致捕获到最终值。使用 let 可以创建块级作用域,为每次迭代生成独立的绑定,从而正确捕获当前索引值。
立即学习“Java免费学习笔记(深入)”;

// 错误示例:所有回调都输出 5
for (var i = 0; i < 5; i++) {
setTimeout(() => console.log(i), 100);
}
// 正确示例:输出 0, 1, 2, 3, 4
for (let i = 0; i < 5; i++) {
setTimeout(() => console.log(i), 100);
}基于循环中 let 绑定的具体行为
当使用 let 时,JavaScript 引擎会在每次循环迭代中创建一个新的词法环境。每个闭包都绑定到这个特定的环境实例,因此它们各自持有不同的 i 值副本。这种机制确保了即使异步操作延迟执行,也能获取到预期的迭代值。


















