总所周知,js在运行时,会有三个阶段,分别是:
其中,所谓的预编译阶段,就是在内存中开辟一些空间,存放一些变量与函数对这些内存中每一个通道进行编译。从代码的层面来看,预编译阶段给代码的执行提供了执行期上下文(执行环境)。
在js语言中,预编译分为两种:
首先,让我们先来看一段代码:
<script>
var a = 1;
console.log(a);//1
console.log(b);//undefined
fn(1,2);//3 2 2
function fn(a,c){
var a = 3;
var b = 2;
console.log(a,b,c);
}
var b = 3;
</script>
如上代码十分简单,下面让我们以这段代码为例子,展示一遍预编译的过程。
1.1- 全局的预编译
全局的预编译发生在页面打开之后,代码执行之前,只会发生一次,且遵循以下步骤:
GO = {
}
GO = {
a : undefined,
b : undefined
}
GO = {
a : undefined,
b : undefined,
fn : function(a,c){
var a = 3;
var b = 2;
console.log(a,b,c);
}
}
至此,全局的预编译就完成了。
1.2- 全局的代码执行
当js代码执行的时候,是从上到下执行的。首先第一行,将1赋值给a;
GO = {
a : 1,
b : undefined,
fn : function(a,c){
var a = 3;
var b = 2;
console.log(a,b,c);
}
}
第二行,在控制台打印a,此时a的值为1,故打印1;
第三行,在控制台打印b,此时b的值为undefined,故打印undefined;
第四行,调用fn函数,此时进行函数的局部预编译:
2.1- 函数的局部预编译
局部的预编译发生在函数被调用的时候,每次函数被调用,都会预编译相对应的AO,局部的预编译遵循以下步骤:
AO = {
}
AO = {
a : undefined,
c : undefined,
b : undefined
}
2.2- 函数的代码执行
AO = {
a : 1,
c : 2,
b : undefined
}
AO = {
a : 3,
c : 2,
b : 2
}
1.3- fn执行结束后,还有一句全局环境的js代码未执行,故执行它
将3赋值给b
GO = {
a : 1,
b : 3,
fn : function(a,c){
var a = 3;
var b = 2;
console.log(a,b,c);
}
}
以上,所有代码执行完毕,GO始终保留在内存里不会被销毁,除非这个页面被关闭。