美文网首页
关于js中的闭包

关于js中的闭包

作者: 默默无闻的小人物 | 来源:发表于2022-03-28 10:33 被阅读0次
    • 什么是闭包?个人理解

    个人觉得闭包没有那么复杂,本质就是上级作用域内变量的生命周期,因为被下级作用域内引用,而没有被释放。就导致上级作用域内的变量,等到下级作用域执行完以后才正常得到释放。

    • 闭包是怎么形成的?

    我认为比较容易理解的闭包定义:函数嵌套函数时,内层函数引用了外层函数作用域下的变量,并且内层函数在全局环境下可访问,进而形成闭包。

    看以下简单的示例:

    function numGenerator(){
      let num = 1
      num++
      return () => {
        console.log(num)
      }
    }
    var getNum = numGenerator()
    getNum()
    

    在这个简单的闭包示例中,numGenerator创建了一个变量num,接着返回打印num值得匿名函数这个函数引用了变量num,使得外部可以通过调用getNum 方法访问变量num,因此在numGenerator执行完毕后,即相关调用栈出栈后,变量num不会消失。仍然有机会被外界访问。

    f12查看Chrome devtool可以看到 num被标记为Closure,即闭包变量。

    image.png
    • 闭包基本原理

    我们知道在正常情况下外界是无法访问函数内部变量的,函数执行之后,上下文即被销毁。但是在函数(外层)中,如果我们返回了另一个函数,且这个返回的函数使用了函数(外层)内的变量,那么外界便能够通过这个返回的函数获取原函数(外层)内部变量值,这就是闭包基本原理。

    下面来看几个例子

    例题1:
    const foo = (function (){
              var v= 0
              return () =>{
                  return v++
              }
          }())
          for(let i = 0; i< 10; i++){
              foo()
          }
          console.log(foo());
    

    上面代码输出的答案是10。分析一下这道题,
    foo是一个立即执行函数,调用的时候他要先执行如下代码:

    function (){
              var v= 0
              return () =>{
                  return v++
              }
        }()
    

    此时形成的闭包v已经加了1 已经为1,后面再调用十次,从1开始累加10次,答案是10

    例题2:
    const foo = () => {
      var arr = []
      var i
      for(i=0; i< 10; i++){
        arr[i]= function(){
          console.log(i)
        }
      }
      return arr [0]
    }
    foo()()
    

    答案:10. 因为自由变量i,类似例题1,执行foo返回的是arr[0],arr[0]此时是函数。但是自由变量已经执行了10次,变成了10,所以再调用arr[0]里面的函数就会打印10

    例题3:
    var fn = null
    const foo = () =>{
          var a = 2
          function innerFoo(){
              console.log(a)
          }
              fn = innerFoo
          }
          const bar = () =>{
              fn()
          }
          foo()
          bar()
    

    答案为2.
    正常来讲,foo函数执行完毕后,其执行环境生命周期会结束,所占用的内存会被垃圾收集器释放,上下文消失、但是通过innerFoo函数赋值了给全局变量fn,foo的变量对象a就会保留下来。这就跟例题1中 return () =>{ return v } 返回了变量一样。然后被引用。所以依然可以访问到这个被保留下来的对象。

    • 闭包的作用

    闭包就是能够读取其他函数内部变量的函数。例如在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。

    相关文章

      网友评论

          本文标题:关于js中的闭包

          本文链接:https://www.haomeiwen.com/subject/vaxpjrtx.html