JavaScript预编译过程

什么是预编译?

为了利于理解我们可以把这个过程简化成下面的内容,这和学习课本的内容一样,你学习的知识不一定是对的,但是确实是你能接受范围内最形象的表达,有基础的朋友可以看我的另一篇博客

《JS深入理解执行过程:作用域和作用域链,执行上下文,预编译等》

当js代码执行时有三个步骤:

1,语法分析,这个过程检查出基本的语法错误。

2,预编译,为对象分配空间。

3,解释执行,解释一行执行一行,一旦出错立即停止执行。

预编译发生在代码执行的前一刻。

预编译的具体过程:

预编的时候会生成AO (Activation Object,暂且可以叫做执行期上下文,详情请看上文推荐博客)和GO (Global Object,等于window)

【注1】先生成GO,生成后会逐行执行代码,遇到某个函数要执行时,在执行前的前一刻会预编译这个函数,生成AO,

换言之,AO用于全局中的某个具体函数,而GO用于整个全局,详情请看下面例子:

                  

运行结果如下:

                

GO创建过程:

1.首先创建GO对象。

      GO{}

2.在全局中寻找变量声明作为GO的属性,并将undefined赋给它。

      GO{

                b:undefined;

}

3.在全局中寻找函数声明(【注2】注意不是函数表达式)作为GO属性,并将函数体赋值于它。

       GO{

                b:function{...};(此时第二步中的b已被覆盖成为function b);

}

然后开始逐行执行代码,遇到第一个console.log(b);打印的是GO中的b;

AO创建过程:

第一次打印完b后,代码执行到 然后开始创建AO,其创建过程和GO相似只是多了一步实参形参相统一而已。

1.创建AO对象。

      AO{}

2.在相应函数中寻找形参和变量声明作为执行期上下文的属性,并将undefined赋给它们。

     AO{

         b:undefined;(这个b是变量b,此函数没有形参)

}

3.实参形参相统一。

4.寻找函数声明作为它的属性,并将函数体赋给它。

      AO{

         b:function{...};(函数b将变量b覆盖)

}

开始执行函数b,第二个console.log(b)结果为function(){},

执行AO中b的值被赋成10,执行第三个console.log(b)结果为10.

【注1】:GO和AO生成之后会存在计算机中供执行时候调用。

【注2】:函数声明,函数表达式,匿名函数是不一样的,

函数声明是声明一个函数。

function qian (){};

函数表达式则是表达式的一种,等式右边函数名字存在意义不大。

var test = function qian (){};

匿名函数,一般用于函数表达式的一部分,在闭包中经常用到。

function (){};

//2019.12.3

二更,当时写这篇文章时候对JS其实不算非常了解,现在看起来真的是在各位大佬面前‘班门弄斧’,有机会更新更深层次的预编译过程。

猜你喜欢

转载自blog.csdn.net/qq_41995398/article/details/89815503