闭包首先是个函数,他可以访问另一个函数作用域中的变量。比较常见的方式就是一个父函数中创建一个子函数。
在了解闭包之前需要捋清楚作用域、执行环境、作用域链还有变量对象、活动对象这些名词。
执行环境
执行环境具体是什么,暂时还是不是十分清楚,目前所知的执行环境就是全局执行环境和函数。当执行流执行结束当前的执行环境,当前的执行环境就将被释放出执行栈。
作用域
作用域属于执行环境,函数的执行环境就叫做作用域
变量对象
变量对象是包含了执行环境中所有变量和函数的一个对象,每个执行环境中都有一个变量对象。全局执行环境的变量对象是window。
活动对象
函数的执行环境中的变量对象就是活动对象
作用域链
作用域链是执行环境中变量对象的引用栈,作用域链被存放在内部的[[scope]]属性中,当函数被调用的时候会创建一个当前的执行环境,然后会复制之前的作用域链然后将当前的活动对象添加到作用域链中,这样就形成了当前执行环境中的作用域链。全局执行环境始终是在作用域链的后端或底部。
块作用域的理解
块作用域只能是一个执行环境,不是只有花括号就可以,他本质上也还是一个执行环境,所以说函数是一个块作用域,但是for循环的花括号不是。
所以这样会引起一个叫变量提升的问题,在for循环中如果定义了一个元素,但是他是会被放到执行环境的最上面,变成了整个执行环境中都可以访问到的变量。
闭包
闭包实质上就是有权访问另一个函数作用域中的变量的函数,闭包比较常见的一个创建方式是在一个函数中创建另一个函数(书中描述)
闭包中子函数作用域可以访问父函数作用域变量的缘故是:子函数的作用域链中包含有父函数作用域中的活动对象
为什么父函数在执行完成之后其变量对象未被释放,而子函数可以调用呢? 主要是依据垃圾回收机制中的引用计数,当该变量引用的次数为0的时候才会被销毁,否则不会被销毁 子函数在被返回的时候就将父函数的活动对象保存到当前执行环境的作用域链中了
那么子作用域链中是什么时候将父活动对象添加的呢? 子函数在被返回的时候就将父函数的活动对象保存到当前执行环境的作用域链中了
注:如有错误,敬请指出!!!