什么是闭包

  • 首先是作用域,全局作用域,函数作用域也叫局部作用域。而后又加了块级作用域
  • 函数内部可以这直接读取全局作用域的变量或者方法。但是在函数外部无法读取函数内部的局部变量。
  • 闭包就是能够读取其他函数内部变量的函数。闭包就是将函数内部和函数外部数据建立连接的桥梁。

    闭包的概念

  • 由于对一个变量的存有引用不会被引擎执行销毁过程。始终保持在内存中,外部无法直接访问。

  • 内部函数因为访问了外部函数的变量而不会被销毁就会形成闭包。直观的说就是形成一个不销毁的栈环境。
  • 存在自用变量的函数就是闭包
  • 在JavaScript中,每当函数被创建,就会在函数生成时形成闭包。

    闭包的用途

    闭包可以从外部函数访问内部函数作用域的一种方式

    ```javascript let state = (() => { let s = ‘string’; let n = 10; return () => { console.log(n); n++; return s } })();

state() // ‘string’ ; ++ -> 11 -> 12 n //err 访问不到

  1. <a name="kPg8h"></a>
  2. #### 可以防止对全局环境的变量污染
  3. ```javascript
  4. let o1 = (
  5. () => {
  6. let obj = {
  7. s: 10
  8. }
  9. return obj
  10. }
  11. )();
  12. let o2 = (() => {
  13. let obj = {
  14. s: 20
  15. }
  16. return obj
  17. })();
  18. o1.s // 10
  19. o2.s// 20
  20. 也可以是一个具体的值

模拟私有变量

  1. let Counter = (function() {
  2. let privateCounter = 0;
  3. function changeBy(val) {
  4. privateCounter += val;
  5. }
  6. return {
  7. increment: changeBy.bind(null,1),
  8. decrement: changeBy.bind(null,-1),
  9. get value() {
  10. return privateCounter;
  11. }
  12. }
  13. })();
  • 必须通过匿名函数返回的三个公共函数访问
  • 单独的方法对上层作用域的方法变量有引用关系,所以不会被删除

    对内部变量的引用

    ```javascript function add () { let num = 10; return func(arg){
    if(arg){
    num += arg;
    return 
    
    } num += 1 } }

let func = add(); func() //num 11 func(2) //func 13 //通过闭包对外层作用域变量的引用,函数执行完毕不会被回收掉 ```

  • 可以读取函数内部的变量
  • 可以让这些变量始终存在内存中

    闭包使用的注意点

  1. 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除