• JS采用词法作用域(lexical scoping), 函数的执行依赖变量作用域。作用域在函数定义时决定,而非调用时
    • 当前函数的变量保存在函数作用域内(闭包)
    • 闭包指函数变量可以被隐藏于作用域链之内,象是函数将变量”包裹”了起来
  • 每函数中引入当前作用域链
  • 定义时与运行时
    • 大多定义函数时的作用域链在调用函数时依然有效
    • 调用函数时与定义函数时作用域链不是同一个时
      • 如返回内部嵌套的函数a时,外部运行a,其作用域链仍然是a的作用域链而非外部作用域链
  • 作用
    • 捕捉局部变量并一直保存
  • 原理
    • 如果一个函数的局部变量定义在cpu栈中, 函数返回时它们的确不存在了
    • js中作用域链是一个对象列表,不是绑定的栈。
      • 运行js函数a时, 都创建新的对象保存局部变量。该新对象添加到作用域链中
        • 函数a返回时,从作用域链中删除该局部变量对象,等待垃圾回收
        • 如果a有嵌套函数,每个嵌套函数各自对应一个作用域链 # 该嵌套函数的作用域链,保留a的局部变量对象
          • 嵌套函数在a中局部变量对象中保存时,会随其一起从作用域链删除
          • 嵌套函数被返回或被外部引用时, 该嵌套函数不被回收,且其自身作用域链中的自身局部变量对象、a的局部变量对象也不删除。
    • 闭包的this值会随外部调用者而变动,所以要先将this转存。var self = this;
      • 闭包中使用的arguments也会变动,也要转存。var outerArguments = arguments;