闭包
闭包是有权访问函数作用域内变量的函数。就是指利用一个函数来访问另外一个函数内部变量。这个函数就称为闭包函数。
而能访问内部变量的原因是,内部函数的环境变量包含了外部函数的环境变量。
作用域链
当代码在一个环境中执行时,会创建变量对象的一个作用域链,作用域链的作用是能够让你有序的去访问有权访问的变量和函数,不至于混乱不堪,搞不清他们的层级关系。下级的变量对象包括上级的。如果是函数的话,初始化变量对象只包含一个arguments对象。
作用域链本质上是一个指向变量对象的指针列表,它只引用但不实际包含变量对象。
一般当调用一个函数的时候,就会在作用域链上查询需要的变量,函数执行完毕,变量对象就会销毁,内存中仅保存全局变量对象。而闭包就不一样了。
因为内部函数的存在,它的作用域链里会添加外部的变量对象,也就是即使外部函数作用域链销毁了,但是他的变量对象还需要存在,因为在闭包的(初始化)的时候,外部的变量对象就已经被内部的函数引用了,如果函数不被销毁指针,那么它会一直引用这个变量对象。
环境变量
全局环境变量始终存在,除非程序关闭,而一个单独的函数的局部环境的变量对象只在函数调用时候存在。
闭包的弊端
闭包包含了它的函数作用域,因此它占用了更多内存,过度使用闭包会导致内存占用过多,v8已经开始尝试回收闭包占用的内存。
闭包与变量
由于作用域链的机制,闭包只能获取变量对象里的定义的变量的最后一个值,也就是初始化形成以后的最终变量。
这样如果要记录之前变量的变化,那么只有将它每次的变化作为参数,传递给函数,那么每一个函数都保存一个变量,在这个函数里的闭包拿到的就是所记录的每次变量记录。
关于闭包不能直接取到外部函数的this
函数的特性里,当内部函数在搜索变量时候,只会搜索到当前活动对象为止,因此无法向上查询。因为这两个对象是函数调用的时候就形成的,每个函数都有,所以它不需要向上查找。
那么这时候将上层的this定义好以后,就可以随时替换this了。
会造成内存泄露
可以用模仿块级作用域
创建私有变量
静态私有变量
模块模式
增强模块模式
小结:后面几个下次补上。