zoukankan      html  css  js  c++  java
  • var 的迷惑行为(作用域提升 preprocess, 现在叫 BoundNames)

    var的作用域提升

    我们先来看下面的代码

    for(; i < 10; i++) {
      let i = 0;
      console.log(i)
    }
    // Uncaught ReferenceError: i is not defined at <anonymous>:1:9
    

    这意味着let 并不会有作用域的提升

    接下来我们看下面的代码

    var i = 0
    for(;i < 10; i++) {
      let i = 0;
      console.log(i);
    }
    // 输出了 10 个 0
    

    我们来分析一下这段代码,我们看到,开始的用 var 定义的 i,在循环体里面随着 i <10 做了十次自增。然后在子作用域里面又存在着一个自作用于里面的 i,循环了十次,输出了 10 次 let i = 0

    紧接着,我们再看看下面的这段代码

    for(; i < 10; i++) {
      let i = 0;
      console.log(i);
    }
    // Uncaught ReferenceError: i is not defined at <anonymous>:1:9
    

    然后对比这个

    for(; i < 10; i++) {
      var i = 0;
      console.log(i);
    }
    // undefined
    

    再看看这个

    for(let i = 0; i < 10; i++) {
      let i = 0;
      console.log(i);
    }
    // 输出了 10 个 0,只是说在这里面就拿不到 i 了
    
    // 以上这个我们可以理解为 父作用域和子作用域,类似于:
    {
      let i =0;
      {
        let i = 1;
        console.log(i);
     	)
      console.log(i);
    }
    // 1 0
    

    var 是有迷惑行为的(var 预处理机制)

    for(i = 0; i < 10; i++) {
      var i;
      console.log(i);
    }
    
    // 等同于
    var i;
    for(i = 0; i < 10; i++) {
      console.log(i);
    }
    
    //等同于
    for(i = 0; i < 10; i++) {
      console.log(i);
      var i;
    }
    //甚至等同于
    for(i = 0; i < 10; i++) {
      console.log(i);
    }
    var i;
    
    // Weird code
    var x = 0
    function foo() {
      var o = { x: 1 }
      x = 2
      // var x = 2
      // 'with' declared a seperate block
      with (o) {
        var x = 3
      }
      console.log(x)
    }
    foo()
    console.log(x)
    

    也就是说,不管 var 加在函数里面的什么地方,var 自动会变量提升到函数的最开始,对整个函数进行赋值操作,这是很迷惑的一个东西
    所以,以后用 var,一定要在文件、函数的最开头声明

    Brendan Eich:javascript-[with,var]这俩就是两个设计错误

    winter:

    1. 如果非要用 var ,不建议大家写在任何的语句的子结构里面。有 var,我们一定要写在 function 的范围内,并且写在最前面,至少要写在第一次这个变量名出现的地方

      function foo() {
        var o = {x: 1};
        x = 2;
        if(false) {
          // 这句 var x = 1,也改变了 x = 2 的行为
          var x = 1;
        }
        console.log(x);
        
        return
        // 这个 x = 3,照样改变了上面 x = 2 的行为
        var x =3
      }
      foo()
      console.log(x);
      
    2. 不要在任何的 block 里面写 var,其实在有的javascript编程规范里面建议完全舍弃 var,就用 let 还有 const,痛苦一点但是 resonable

  • 相关阅读:
    9-10-堆 Windows消息队列(25 分)
    9-7 二叉搜索树的结构(30 分)
    9-4 笛卡尔树(25 分)
    9-3 搜索树判断(25 分)
    7-9 堆中的路径(25 分)
    个人总结
    软工网络15个人作业4——alpha阶段个人总结
    软件工程网络15个人作业3——案例分析(201521123029 郑佳明)
    软件工程15 结对编程作业
    软件工程网络15个人阅读作业2(201521123029 郑佳明)
  • 原文地址:https://www.cnblogs.com/ssaylo/p/12984387.html
Copyright © 2011-2022 走看看