js 闭包


闭包:

  • 闭包的概念:引用了另一个函数作用域中变量的函数,通常是在嵌套函数中实现的

    • 注:其实就是有一个函数a,它内部又定义了一个函数b,这个b引用了a中的变量,就产生了闭包
  • 闭包的作用:

    1. 延长了局部变量的生命周期闭包不再使用时一定要记得释放内存!!!切记!切记!
    2. 隐藏变量,避免全局污染
  • function fun() {
        // 闭包产生,函数fn声明提升,引用了fun内的局部变量a
        let a = 0
        function fn() {
            return a++
        }
        return fn
    }
    
    // f指向fn中存放的函数,在fun调用结束后,fn这个变量已经销毁了(它只是存放的函数的地址值)
    let f = fun()
    console.log(f()); // 0
    console.log(f()); // 1
    console.log(f()); // 2
    // 闭包死亡(f不再指向该函数,所以这个函数对象变成了垃圾对象,会被回收)
    f = null
    
  • 面试题:

    • 第一题

      // 值得注意的是,这个并不是一个闭包,因为里面的函数并没有引用外部函数的变量
      var name = "The Window"
      var object = {
        name: "My Object",
        getNameFunc() {
          return function () {
            return this.name
          }
        }
      }
      /* 
       第一个()调用:
       object.getNameFunc() ==> 返回了内部的函数,下面用fn来代指这个函数
       第二个()调用:
       fn() 可以看出这个调用的this其实就是window了,所以打印出的是 The Window
      */
      console.log(object.getNameFunc()()) // The Window
      
      
    • 第二题

      var name = "The Window"
      var object = {
        name: "My Object",
        getNameFunc() {
          // 这个就比较简单了,then保存了当前函数的this,指向了object,这个then变量只要闭包存在就不会被回收,所以输出是 My Object
          var then = this
          return function () {
            return then.name
          }
        }
      }
      
      console.log(object.getNameFunc()()); // My Object
      

附加小知识:

  1. 内存溢出:当程序运行需要的内存超过了剩余的内存时,就会抛出内存溢出的错误

  2. 内存泄漏:

    • 占用的内存没有及时释放

    • 内存泄露积累多了就容易导致内存溢出

    • 常见的内存泄漏:

      • 意外全局变量(没有使用关键字声明)
      • 没有及时清理的计时器或回调函数
      • 闭包
js