JavaScript进阶篇(七)——闭包

1.如何产生闭包

当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时,就产生了闭包

function fn1(){
    
    
        // 此时闭包就已经产生了(函数提升,内部函数对象已经)
        var a = 2
        function fn2(){
    
      // 执行函数定义就会产生闭包(不用调用内部函数)
          console.log(a)  
        }
      }

2.闭包是什么?

理解一:闭包是嵌套的内部函数
理解二:包含被引用变量(函数)的对象
注:闭包存在于嵌套的内部函数中

3.产生闭包的条件?

  • 函数嵌套
  • 内部函数引用了外部函数的数据(变量、函数)

4.常见的闭包

4.1 将内部函数作为外部函数的一个返回值返回

外部函数被调用几次,就产生了几次闭包,这里只产生了一次闭包

   function fn1 () {
    
    
        var a = 2
        function fn2 () {
    
    
          a++
          console.log(a)
        }
        return fn2
      }
      // fn1的地址值传给了f,fn1销毁了,f还存在
      var f = fn1()  // 产生闭包,返回的是内部函数
      f()   // 3  调用的是fn2
      f()   // 4

4.2 将函数作为实参传递给另一个函数使用

 function showDelay (msg, time) {
    
    
        setTimeout(function () {
    
    
          alert(msg)
        }, time)
      }
      showDelay('hello', 2000)

5.闭包的作用

  1. 使用函数的变量在函数执行完后,仍然存活在内存中(延长了局部变量的生命周期)
  2. 让函数外部可以操作(读写)到函数内部的数据(变量/函数)

6.问题

1.函数执行完后,函数内部声明的局部变量是否还存在?
一般是不存在的,存在于闭包中的变量才有可能存在

2.在函数外部能直接访问函数内部的局部变量吗?
不能,但我们可以通过闭包让外部操作它

7.闭包的生命周期

产生: 在嵌套内部函数定义执行完成时就产生了(不是在调用)
死亡:在嵌套的内部函数成为垃圾对象时

	  function fn1 () {
    
    
	  // 此时闭包已经产生了(函数提升,内部函数对象已经创建了)
        var a = 2
        function fn2 () {
    
    
          a++
          console.log(a)
        }
        return fn2
      }
      var f = fn1()  
      f()   // 3  
      f()   // 4
      f = null  // 闭包死亡(包含闭包的函数对象成为垃圾对象)

猜你喜欢

转载自blog.csdn.net/weixin_42164004/article/details/110792455