最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • ES6 let解决的闭包问题

    正文概述 掘金(廊坊吴彦祖)   2020-12-10   470

    ES6 let

    let 是 ES6 新增的命令,用来声明变量

    let 用法和 var 类似,区别:
    • var 声明变量存在变量提升,let 不存在变量提升
    • var 可以重复声明变量,let 不可以重复声明
    • let 声明变量存在块作用域({} 内)

    js 闭包

    闭包 就是能够读取其他函数内部变量的函数。由于 js 作用域链,只有函数内部的子函数才能读取函数内部的局部变量,所以可以把闭包简单理解成"定义在一个函数内部的函数",本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁

    闭包用途:
    • 使函数外部能够读取函数内部的变量
      function fn() {
          var num = 1
          //闭包:getNum函数通过作用域链可以访问到变量num,并将其返回到fn函数外部
          return function getNum() {
              return num
          }
      }
        
      //变量num为fn函数的局部变量,函数外面无法访问
      console.log(num)   //报错:num is not defined
        
      //getNum函数作为fn函数的返回值被赋值给n,执行n返回num
      var n = fn()
      console.log(n())   //1
      
    • 让函数内部变量的值始终保存在内存中
      function add() {
          var num = 1
          //闭包:addNum函数通过作用域链可以访问到变量num,并将其的累加值返回到add函数外部
          return function addNum() {
              return num++
          }
      }
        
      //addNum函数作为add函数的返回值被赋值给全局变量n,执行n返回num的累加值
      //add函数内部引用着add函数里的变量num,所以变量num始终被保存在内存中,不会被释放
      var n = add()
      console.log(n())   //1
      console.log(n())   //2
      console.log(n())   //3
      

    使用 let 解决的闭包问题

    举例:预期输出 0 1 2 3 4

    for(var i = 0; i < 5; i++) {
        setTimeout(function() {
            console.log(i)
        }, 0)
    }
    
    实际输出:

    ES6 let解决的闭包问题

    分析:

    由于 js 是单线程的,按照 js 的事件循环机制,在执行同步任务 for 循环时,异步任务 setTimeout 定时器被放到任务队列中排队等待执行,等待 for 循环执行完,此时 i 的的值已经为5,任务队列中的五个 setTimeout 开始执行,访问到的 i 的值都为5,所以打印出来五个5

    问题:

    全局作用域中 var 声明的变量为全局变量,每次循环 i 的值不能被保存,这就会出现闭包问题

    使用立即执行函数解决:

    for(var i = 0; i < 5; i++) {
        (function(i) {
            setTimeout(function() {
                console.log(i)
            }, 0)
        })(i)
    }
    
    输出:

    ES6 let解决的闭包问题

    分析:

    在 for 循环中,将 setTimeout 定时器放到一个立即执行函数中,将每次循环 i 的值保存到函数作用域里,作为参数传递给 setTimeout,在执行五个 setTimeout 时访问到的 i 为当前函数作用域里每次循环保存起来的 i 的值,所以打印出来0 1 2 3 4

    总结:

    利用函数作用域形成闭包,保存每次循环 i 的值

    使用 let 解决:

    for(let i = 0; i < 5; i++) {
        setTimeout(function() {
            console.log(i)
        }, 0)
    }
    
    输出:

    ES6 let解决的闭包问题

    分析:

    将 for 循环中的 var 改为 let,这样在每次 for 循环之前都会生成一个块级作用域,每个块级作用域互不干扰,let 声明的变量 i 只在当前循环的块级作用域中有效,每一次循环的 i 都被声明为一个新的变量,在执行五个 setTimeout 定时器时访问到的 i 为当前块级作用域里声明的 i 的值,所以打印出来0 1 2 3 4

    总结:

    利用块级作用域形成闭包,保存每次循环 i 的值


    起源地下载网 » ES6 let解决的闭包问题

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元