JavaScript 闭包(Closure).md
闭包
如果在内部函数使用了外部函数的变量, 就会形成闭包. 闭包保留了外部环境的引用
如果内部函数被返回到了外部函数的外面, 在外部函数执行完后, 依然可以使用闭包里的值
闭包的形成
在内部函数使用外部函数的变量, 就会形成闭包, 闭包是当前作用域的延伸。
1 | function a() { |
从代码的角度看, 闭包也是一个对象, 闭包里包含哪些东西呢?
在内部函数b中使用了外部函数a中的变量, 这个变量就会作为闭包对象的属性!!
1 | function a() { |
- 会不会形成闭包?
- 如果形成, 闭包里有什么?
会形成闭包, 由于b的声明是在外部函数a中的, 在内部函数b中使用了b, 会形成闭包。闭包里存放了一个属性, 就是b函数。
1 | function a() { |
会不会形成闭包?
不会形成闭包, 由于在b函数内部定义了变量b, 打印时直接使用的是内部函数里的变量b, 不会形成闭包。
闭包的保持
如果希望在函数调用后, 闭包依然保持, 就需要将内部函数返回到外部函数的外部。
1 | function a() { |
代码注释①中, 调用a函数, 将内部函数b返回, 保存在函数a的外部。
代码注释②中, 调用demo函数, 实质上是调用内部函数, 在函数b的[[scopes]]属性中可以找到闭包对象, 从而访问到里面的值。
闭包要形成: 在内部函数使用外部函数的变量。
闭包要保持: 内部函数返回到外部函数的外面。
闭包的声明周期
- 产生:在嵌套内部函数定义执行完时就产生了(非调用时)。
- 死亡:在嵌套的内部函数称为垃圾对象时。
闭包的应用
- 在函数外部访问私有变量
- 实现封装
- 防止污染全局变量
在函数外部访问私有变量
1 | function a() { |
本来在函数a的外部(全局)不能直接访问内部变量num, 通过闭包就可以使用num变量了
面向对象的封装
1 | function Person() { |
定义了一个函数Person, 一个内部变量uname, 两个内部函数
返回内部函数, 也是使用了闭包特性
这样在Person函数的外部, 通过get和set方法对变量uname进行操作, 这就是面向对象里的封装的思想
自定义模块
…
闭包注意的问题
- 无意识的使用了闭包
- …
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 LT的编程笔记!