closure 是一个与来自其周围(词法)作用域的变量引用一起捆绑的函数。由于 closure 的存在,内部函数保持对其外部函数变量的访问权限即使在外部函数返回之后。
js
function makeCounter() {
let count = 0; // private variable, captured by the closure
return {
inc: () => ++count,
: count,
};
}
a = ();
b = ();
a.(); a.();
b.();
count 从外部无法访问——只有 inc/get 能看到它。这是从 closure 构建的数据隐私。而且每次调用 makeCounter() 都会创建一个新的、隔离的作用域。
经典循环 bug
js
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0); // prints 3, 3, 3 — all share one `i`
}
for (let i = 0; i < 3; i++) {
setTimeout(() => .(i), );
}
使用 var 时,每个回调都会闭合在同一个 i 上(当它们运行时为 3)。let 在每次迭代中创建一个新的绑定。
为什么这很重要
Closures 为模块隐私、memoization、currying、记住状态的事件处理器/回调提供了强大支持,也正是 React hooks(useState)在渲染之间保持值的方式。
