欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JS执行顺序语法分析及预编译讲解

程序员文章站 2022-11-09 09:53:13
一、语法分析 将所有js检查一遍,看有没有语法错误,这里并不会执行,没有错误则进行第二步,预编译 二、预编译 首先要理解函数声明整体提升,变量 声明提升。 这里要注意变量的...

一、语法分析

将所有js检查一遍,看有没有语法错误,这里并不会执行,没有错误则进行第二步,预编译

二、预编译

首先要理解函数声明整体提升,变量 声明提升。

这里要注意变量的提升,一般我们声明一个变量都是

[html] view plain copy

var a = 1;  

console.log(a) //1  

//但实际上拆分成了两步,真正执行是这样的  

var a;  

a = 1;  

console.log(a) //1  

[html] view plain copy

//如果将console.log放a前面会打印出undefined  

console.log(a) //undefined  

var a = 1;  

//因为变量的声明提升了,但是赋值并没有提升,实际上是这样的  

var a;  

console.log(a);  

a = 1;  

1、预编译的时候会创建一个ao对象(activation object)执行上下文;

2、找形参和变量声明,将形参和变量作为ao对象的属性名,值为undefined;

3、将形参和实参统一;

4、在函数体里找函数声明,值赋给函数体

举个例子:

[html] view plain copy

function fn(a){  

<span style="white-space:pre;">    </span>console.log(a);             

    var a = 123;  

    console.log(a);  

    function a(){};  

    console.log(a);  

    var b = function(){};  

    console.log(b);  

    function c();  

}  

fu(1);  

[html] view plain copy

//打印结果依次对应  

function a(){}  

123  

123  

function(){}  

[html] view plain copy

function fn(a){  

    console.log(a);  

    var a = 123;  

    console.log(a);  

    function a(){}  

    console.log(a);  

    var b = function(){}  

    console.log(b)  

    function c();  

}  

fn(1)  

预编译的时候创建一个ao对象:  

1、预编译的时候会创建一个ao对象(activation object)执行上下文;  

ao={  

}  

2、找形参和变量声明,将形参和变量作为ao对象的属性名,值为undefined;  

ao={  

    a : undefined,  

    b : undefined,  

}  

3、将形参和实参统一  

ao={  

    a : 1,  

    b : undefined  //此时b还是undefined,前面已经说了,是变量声明提升,赋值并没有提升  

}  

4、在函数体里找函数声明,值赋给函数体  

ao={  

    a : function a(){},   //此时a的值已经被覆盖了,因为函数声明整体提升  

    b : undefined,         //b不是函数声明,是函数表达式  

    c : function c(){}  

}  

最后执行的时候是从ao里面取值  

第一个console.log(a) 打印 function a(){}  

第二个console.log(a) 因为又重新定义了a,所以打印 123  

第三个console.log(a) 和第二个同理,打印 123  

第四个console.log(b) 因为把一个函数赋值给了b,所以打印 function (){}  

三、语句执行

[html] view plain copy

最后执行的时候是从ao里面取值  

第一个console.log(a) 打印 function a(){}  

第二个console.log(a) 因为又重新定义了a,所以打印 123  

第三个console.log(a) 和第二个同理,打印 123  

第四个console.log(b) 因为把一个函数赋值给了b,所以打印 function (){}  

function fn(a){  

    /*  

        *这里都是隐式声明  

        var a,b;这里的变量提升到函数头部,但是赋值不会提升  

        a = 1;形参赋值  

        a = function a(){}  因为又有一个函数a,函数声明整体提升  

        c = function c(){}  因为有一个函数c,函数声明整体提升  

        然后开始从上往下执行  

    */  

    console.log(a);  

    var a = 123;  

    console.log(a);  

    function a(){}  

    console.log(a);  

    var b = function(){}  

    console.log(b);  

    function c();  

}  

fn(1);