首页 > 编程学习 > JS 闭包

JS 闭包

发布时间:2022/1/17 12:38:32

开发了N年,第一次想着看一看闭包是什么,呵呵。不懂不丢人,学就行了。

什么是闭包?先看示例(所有代码均在node.js vue环境下)

示例一

 myFuction() {
      var name = 'homey'
      return function() {  //匿名函数
        return name
      }
    },

  var b = this.myFuction() //b是全局变量
  console.log(b())

解说

在上面代码中,a()中的返回值是一个匿名函数,这个函数在a()作用域内部,所以它可以获取a()作用域下变量name的值,将这个值作为返回值赋给全局作用域下的变量b,实现了在全局变量下获取到局部变量中的变量的值

示例二

 myFuction() {
      var num = 3
      return function() {
        var n = 0
        return (++num + '   ====   ' + ++n)
      }
    },

  var b = this.myFuction()
  console.log(b())
  console.log(b())

解说

 一般情况下,在函数fn执行完后,就应该连同它里面的变量一同被销毁,但是在这个例子中,匿名函数作为fn的返回值被赋值给了fn1,这时候相当于fn1=function(){var n = 0 ... },并且匿名函数内部引用着fn里的变量num,所以变量num无法被销毁,而变量n是每次被调用时新创建的,所以每次fn1执行完后它就把属于自己的变量连同自己一起销毁,于是乎最后就剩下孤零零的num,于是这里就产生了内存消耗的问题

示例三

    myFuction() {
      for (var i = 0; i < 5; i++) {
        console.log(i + '  **** ')
        setTimeout(function() {
          console.log(i)
        }, 10)
      }
    },

    this.myFunction()

 解说

按照预期它应该依次输出1 2 3 4 5,而结果它输出了五次5,这是为什么呢?原来由于js是单线程的,所以在执行for循环的时候定时器setTimeout被安排到任务队列中排队等待执行,而在等待过程中for循环就已经在执行,等到setTimeout可以执行的时候,for循环已经结束,i的值也已经编程5,所以打印出来五个5,那么我们为了实现预期结果应该怎么改这段代码呢?(ps:如果把for循环里面的var变成let,也能实现预期结果
 

Copyright © 2010-2022 ngui.cc 版权所有 |关于我们| 联系方式| 豫B2-20100000