zoukankan      html  css  js  c++  java
  • JS中的变量声明提升

    JS是一种脚本语言,和一些高级语言不同,它没有完整编译的过程,一般是边写边编译,这也是我们觉得脚本语言比其他语言加载快的原因,其实,JS中有变量声明提升这一机制。当JS在执行的时候会分为2个阶段,预解析,执行,当JS在执行的时候会将所有用var声明的变量以及关键字定义的函数进行提升(  function  fn(){......}  ),提升到当前作用域的最顶端,而赋值语句在原地等待执行,预解析后,再从上往下逐行解析代码。预解析遵循一些原则,下面一点一点的说明。

    提到变量声明提升,就得结合作用域来分析,也就是局部作用域能访问到全局的变量,而全局作用域访问不到局部作用域。

    例:

      var a=1;

      function fn(){

        alert(a);

         a=2;

      }

    fn();      

    alert(a);

    当fn执行后,会弹出1,因为局部作用域能访问到全局作用域,代码逐行执行,这个a就是上面声明的那个a,但在全局再弹出a,a变成了2,因为函数内部对它进行的更改。

    例:

      var a=1;

    function fn(){

      alert(a)

      var a =2;

    }

    fn();

    alert(a);

    这时,函数内部弹出的a是undefined,因为函数内部声明了一个a,进行了变量声明提升,提升到当前作用域的最顶端,赋值语句不动,也就是函数变成了下面这样

    function fn(){

      var a;

      alert(a)

       a =2;  //这里的a 是指函数内部的a,不管全局作用域还是局部作用域都遵循就近原则。

    }

    全局弹出的a是1,因为全局访问不到局部变量,即使在函数中var 了一个a但访问不到。

    例:

    var a=1;

    function fn(a){

      alert(a);

      a=2;

    }

    fn();

    alert(a);

    函数内弹undefined,全局弹1.但这个和上一个例子不一样。函数传一个参数,就相当于在函数内声明了一个变量,所以函数内弹undefined,全局仍然弹1

    例:

      

    var a=1;

    function fn(a){

      alert(a);

      a=2;

    }

    fn(a);

    alert(a);

    函数内弹1,因为函数调用的时候把全局的a传了进去,别看全局和函数都有个a,但2个a是不一样的,不是同一个变量,全局仍然弹1

    下面上几个有难度的,

     alert(a);

    var a=1;

    alert(a);

    function a(){alert(2)}

    alert(a);

    var a=3;

    alert(a)

    function a(){alert(4)}

    alert(a)

    a();

    第一看到这些代码谁都头大,不过我们来一点一点的看。

    首先,JS运行代码会先进行预解析,var 的a拿到当前作用域的顶部,此时顶部有一个a,往下走,就找var 和关键字定义的函数,function a(){},又找到一个,然后它会把原来顶部的a替换掉,当遇到重名的变量只会留一个,遇到函数,函数的优先级高,所以留函数,此时顶部的a为一个函数体,也就是function a(){alert(2)},又找到下一个函数a,   a又被替换掉,预解析过程就完成了,再逐行解析代码,读到第一行,要弹a,此时预解析顶部的a是function a(){alert(4)},所以会弹出这个函数体,再读,给a赋值1,那么下次会弹出1,再走,碰到函数体,但不是赋值语句,对a没有影响,继续往下走,再弹1,声明一个a并赋值为3,再弹,会弹出3,再遇见函数,不是赋值语句,对a没影响,再弹,还弹3,最后调用a,但此时a是3,不是函数,所以会报错。总结,以上代码会依次弹出   function a(){alert(4)}    ,   1,   1,  3,   3    ,   报错。

      

  • 相关阅读:
    文件参数Python读取wav格式文件
    电子工程术语和定义列表,按字母顺序排列
    MAC地址加减1算法
    uboot通过kernel command line 动态分区 CONFIG_MTD_CMDLINE_PARTS
    c调用shell脚本
    busybox提示can't access tty.job control turned off
    cut命令如何截取以空格隔开的字段
    DS28E01100
    busybox 中的ntpd使用
    Debugfs
  • 原文地址:https://www.cnblogs.com/lzn0330/p/9709654.html
Copyright © 2011-2022 走看看