JS 预解析(ES5)

120 阅读2分钟
    此为本人学习B站pink老师JS所做的笔记,有些过时-仅做笔记

    预解析是指:在执行之前 将变量和函数的声明提升到作用于最前面

    1.JS引擎运行JS分为两步: 预解析 代码执行
      (1) 预解析 JS引擎会将JS里面所有的 var(实测let不会) 还有 function的声明提升到当前作用域最前面
      (2) 代码执行 按照代码书写的顺序从上到下依次执行

    2.预解析分为 变量预解析(变量提升)  和函数预解析(函数提升)
      (1) 变量提升 就是把 变量声明 提升到当前作用域最前面 不提升赋值操作
      (2) 函数提升 就是把 函数声明 提升到当前作用域最前面 不调用操作
          函数表达式提升变量,并且函数表达式调用只能写在函数表达式下面

1.函数提升


    fun();  //可以执行
    function fun(){

        console.log(10)
    }
    fun();  //可以执行
    
    实际上代码会解析成:

    function fun(){   //函数会提升至当前作用域最前面 所以调用fun();位置即使在声明前面也可以使用

       console.log(10)

    }
    fun();
    fun();

2.变量提升

    1.普通变量
    
    console.log(num) //结果为undefined 
    var num = 10;    
    //注意 let定义执行此程序会报错 let定义的变量使用必须在声明下方 所以var ES6被废弃
    
    实际代码解析为:
    var num;           //undefined
    console.log(num)   //undefined
    num = 10;
    
    
    2.函数表达式

    func();  //不可以执行  
    var func = function (){

        console.log("函数表达式不可提前执行")

    }
    func();  //可以执行

    函数表达式可理解为变量,只是存储的是函数
    
    解析为:
    var func;
    func();   //不可执行 此时并未知道是函数
    func = function(){
        console.log("函数表达式不可提前执行")
    }
    func();//可以执行
   
    

3.经典题


    f1();

    console.log(b);
    console.log(c);
    console.log(a);

    function f1(){

        var a = b = c = 9; 
        //相当于 var a = 9;b = 9;c = 9;  b c没有声明直接使用 是全局变量 实测let也一致
        console.log(a)
        console.log(b)
        console.log(c);

    }
    
    代码实际解析为:

    function f1(){

       var a;
       a = b = c = 9;   // 在这里b c 未声明直接使用 视为全局变量
       console.log(a)   // 9
       console.log(b)   // 9
       console.log(c);  // 9

    }
    f1();

    console.log(b); // 9
    console.log(c); // 9
    console.log(a); //报错