知识卡片

闭包捕获的是活动作用域链而非快照

专业/工作 · 414

内容

闭包的本质并不神秘:JavaScript函数在定义时就绑定了当时的[[作用域链是变量解析的查找链]],这条链在函数返回之后依然作为一个活对象继续存在(不会被当作栈帧销毁),只要还有嵌套函数引用着它就不会被垃圾回收——这就是外部函数”已经返回”却仍能被内部函数访问其局部变量的全部原理。关键的、也是最容易踩坑的一点是:闭包捕获的是这条作用域链本身,而不是变量当时的值,链上的变量随时可被后续代码修改,所有共享这条链的闭包看到的都是同一份最新状态。这解释了for循环里批量创建闭包时的经典陷阱:如果循环变量i声明在闭包函数外层,所有闭包最终读到的都是循环结束后的同一个i值,而不是各自创建时那一刻的值。

参考来源

《JavaScript权威指南(原书第6版)》第8章《函数》