js预编译

大家都知道,javascript是解释性语言,主要特点为解释一行执行一行。

而在js运行时会进行三件事:1.语法分析 2.预编译 3.解释执行

  • 语法分析会在代码执行前对代码进行通篇检查,以排除一些低级错误
  • 预编译发生在代码执行的前一刻
  • 解释执行就是执行代码

预编译的作用:

1、函数声明整体提升;

即写出一个函数声明,不管写在哪里,系统总会将其提升到逻辑最前面。

2、变量声明提升

例如:

1 document.write(a);
2 var a = 123;
3 //undefinde;

即相当于:

1 var a; //提升
2 document.write(a);
3 a  = 123;
4 //undefinde;

而如果直接console.log(a);浏览器会进行报错。//Uncaught ReferenceError: a is not defined (表示a没有定义);

预编译前奏

1、imply global 暗示全局变量

任何变量,如果变量未经声明就赋值,此变量就为全局对象所有。

例如:

1 function test(){
2     var a = b =123;
3 }
4 test();
5 //因为b变量未经声明,所以当在全局访问a时,a为undefinde,而b为123;
6 window.a   //undefinde
7 window.b  //123

2、一切声明的全局变量,全是window的属性;

预编译四部曲:

  1. 创建AO(Activation object)对象
  2. 找形参和变量声明,将变量声明的名(即变量和形参名)作为AO属性名,值为undefined;
  3. 将实参和形参统一;
  4. 在函数体里面找函数声明,值赋予函数体(注意此处的函数声明要区别于函数表达式)
 1 //例题
 2 function fn(a){
 3         console.log(a);
 4         var a = 123;
 5         console;log(a);
 6         funtion a() {};
 7         console.log(a);
 8         var b = function() {};
 9         console.log(b);
10         function d() {};  
11 }
12 fn(1);

根据预编译四部曲逐步分析:

  • 创建A0{ };
  • 1 AO{
    2         a : undefined;
    3         b : undefined;
    4   }
  • 1  AO{
    2        a: 1;  //a为形参,1为实参;
    3        b: undefined;
    4   }
  • 1   AO{
    2       a : function a(){};
    3       b : undefined;
    4       d : function d() {};
    5   }

    此时,AO对象即创建好了!

此时在分析原题:

 1 function fn(a){
 2         console.log(a);         //a = function a() { };
 3         var a = 123;             //将创建好的AO对象中的a值变为123;
 4         console;log(a);        //123;
 5         funtion a() {};           //函数声明   此处在创建AO对象时已经执行过了,所以不会再执行了
 6         console.log(a);       //123;
 7         var b = function() {};     //函数表达式  将AO对象中的b值变为function (){};
 8         console.log(b);             //function (){};
 9         function d() {};              //函数声明 执行过了,依旧不会再执行了;
10 }
11 fn(1);
12 //最后打印结果: 
13 //function a() { };
14 //123;
15 //123;
16 //function() { };

真正的预编译

多了一个全局的GO{}对象

即先创建创建GO/AO对象; (Global Object):全局对象;

1 //例如:
2 globl = 100;
3 function fn(){
4     console.log(global);       //undefined;
5     global = 200;
6     console.log(global);       //200;
7     var global = 300;
8 }
9 fn();

其中GO{
global : 100;
}
AO{
global : undefined;
}

在执行时,函数会先在其AO{}对象内找相应的变量,如果AO{}中没有,再在全局变量GO{}内寻找。
 1 //例题:
 2 function test(){
 3       console.log(b);             //undefined;
 4       if (a) {
 5             var b = 100;
 6     }
 7     console.log(b);               //undefined   因为在if语句里,此时的a值还为undefined,
 8                                   //所以b不进行赋值。而预编译是不管if()先执行的。
 9     c = 234;
10     console.log(c);               //234;
11 }
12 var a;
13 test();
14 a = 10;
15 console.log(c);                 //234;

GO{
a:undefined;
c:234;
}
AO{
a:undefined;
b:undefined;
}

注:此处的AO{}发生在全局调用test()之后,a=10之前;

 
原文地址:https://www.cnblogs.com/Object-L/p/12061750.html