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