美文网首页
for循环中的闭包

for循环中的闭包

作者: zhenghongmo | 来源:发表于2020-03-12 14:23 被阅读0次
    1. 问题
    • 以下代码中原本是想每次点击对应的目标弹出对应的数字下标0-9,但实际上无论点击哪个目标都会弹出数字10.
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
        <div class="parent">
            <div class="child">0</div>
            <div class="child">1</div>
            <div class="child">2</div>
            <div class="child">3</div>
            <div class="child">4</div>
            <div class="child">5</div>
            <div class="child">6</div>
            <div class="child">7</div>
            <div class="child">8</div>
            <div class="child">9</div>
        </div>
        <script>
           var childArray= document.getElementsByClassName('child')
           for(var i=0;i<childArray.length;i++){
               childArray[i].onclick=function(){
                   console.log(i)
               }
           }
        </script>
    </body>
    </html>
    

    <font color="blue">上面代码中,当执行onclick事件时循环已经结束了,这时打印的i是外部定义的i,此时i=10(变量i和这个函数形成了闭包)</font>

    1. 解决方法

      • 方案1:将var改为let
      let childArray = document.getElementsByClassName('child');
          for (let i = 0; i < childArray.length; i++) {
              childArray[i].onclick = function () {
                  console.log(i);
              }
          }
      

      let定义的变量作用域为块级作用域,只在{}中有效。

      • 方案2:增加闭包
       for(var i=0;i<childArray.length;i++){
          childArray[i].onclick = function () {
                      var copy = i;
                      return function () {
                          console.log(copy);
                      }
                  }();
      }
      
      • 方案3:立即执行函数
      for(var i=0;i<childArray.length;i++){
      (function () {
                  var copy = i;
                  childArray[i].onclick = function () {
                      console.log(copy);
                  };
              })();
      }
      

      上述代码每执行一次,就会产生一个对象存储copy和onclick函数

      • 方案4:与方案3相似
      for(var i=0;i<childArray.length;i++){
          (function (arg) {
          childArray[i].onclick = function () {
              console.log(arg);
          };
          })(i);
       }
      

    相关文章

      网友评论

          本文标题:for循环中的闭包

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