美文网首页
局部变量和 for 循环语句

局部变量和 for 循环语句

作者: 唯泥Bernie | 来源:发表于2017-05-12 01:44 被阅读69次

    这篇只是简单的做下记录吧,作用域在 js 中真是个麻烦的东西,实在有太多的 case by case 的情况,无法用一个原理推出其他的,先来代码:

    <ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
    </ul>
    <script>
      var lis = document.querySelectorAll( 'li' );
      // 用 var 声明循环变量
      for( var i = 0; i < lis.length; i++ ) {
        lis[ i ].onclick = function() {
          alert( i ); // 点击任何一个 li 都是 alert 3
        }
      }
      // 用 let 声明循环变量
      for( let j = 0; j < lis.length; j++ ) {
        lis[ j ].onclick = function() {
          alert( j ); // 点击 li 分别显示 0,1,2
        }
      }
    </script>
    

    用 var 声明的变量不是块级的,所以整个循环过程中 i 变量只有一个,当你注册完 onclick 之后再点击,所有函数引用的是同一个 i,所以 alert 出来的是 i 的最终值 3。而如果用 let 声明为什么会产生不同的效果?

    从常识推断:j 虽然是块级作用域变量,但是仅仅能说明在 for 循环外面拿不到 j。并且 for 循环第一个分号前的代码只会执行一次,即使如果每次循环 j 都是生成一个新的局部变量,那么 j++ 为什么能保持 j 数字的递增呢?

    好吧,只能再去撸下规范。原来规范里面针对这种情况是这么规定的(我依然只是说明下大致的步骤):

    1. 每次循环都会新建一个块级作用域;
    2. 相应的 for 循环第一个分号前所有用 let 声明的局部变量都会重新新建。
    3. 然后把上一次循环后变量的值赋值给这次循环生成的新局部变量(当然是找同名的啦)。

    所以就能解释上面代码用 let 声明的情况了,再写一个示例代码来验证下规范的逻辑:

    for ( let a = 0, b = 10; a < 5; a++, b++ ) {
      console.log( 'a:' + a + ' | b:' + b );
    }
    /*
    结果:
    a:0 | b:10
    a:1 | b:11
    a:2 | b:12
    a:3 | b:13
    a:4 | b:14
    */
    
    for ( let c = 0, d = 10; c < 5; ) {
      console.log( 'c:' + c + ' | d:' + d );
      c++;
      d++;
    }
    /*
    结果:
    c:0 | d:10
    c:1 | d:11
    c:2 | d:12
    c:3 | d:13
    c:4 | d:14
    */
    

    相关文章

      网友评论

          本文标题:局部变量和 for 循环语句

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