什么是预编译?
当js代码执行时有三个步骤:
1.语法分析,这个过程检查出基本的语法错误。
2,预编译,为对象分配空间。
3,解释执行,解释一行执行一行,一旦出错立即停止执行。
预编译发生在代码执行的前一刻。
预编译的具体过程:
预编的时候会生成AO (Activetion 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.