函数闭包
什么是闭包
有权访问另一个函数作用域中的变量的函数,就是闭包。
这是一种闭包
1 | function animal() { |
这也是一种闭包
1 | const name = "cat"; |
name 定义在全局作用域中,getName 在内部输出找不到自己定义的值,因此向外寻找,输出 getName,是一个隐性的闭包。
一个例子记住
函数在创建时,会保存所有父变量对象到其中的[scope]中。函数激活时,会将自身的活动对象添加到作用链的前端
1 | var data = []; |
输出均为3
当执行到 data[0] 函数之前,此时全局上下文的 VO 为:
1 | globalContext = { |
当执行 data[0] 函数的时候,data[0] 函数的作用域链为:
1 | data[0]Context = { |
data[0]Context 的 AO 并没有 i 值,所以会从 globalContext.VO 中查找,i 为 3,所以打印的结果就是 3。
data[1] 和 data[2] 是一样的道理。
所以让我们改成闭包看看:
1 | var data = []; |
当执行到 data[0] 函数之前,此时全局上下文的 VO 为:
1 | globalContext = { |
跟没改之前一模一样。
当执行 data[0] 函数的时候,data[0] 函数的作用域链发生了改变:
1 | data[0]Context = { |
匿名函数执行上下文的AO为:
1 |
data[0]Context 的 AO 并没有 i 值,所以会沿着作用域链从匿名函数 Context.AO 中查找,这时候就会找 i 为 0,找到了就不会往 globalContext.VO 中查找了,即使 globalContext.VO 也有 i 的值(值为3),所以打印的结果就是0。
data[1] 和 data[2] 是一样的道理。
文章参考https://github.com/mqyqingfeng/Blog/issues/9,对其进行了注释方便学习
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 !