初步了解预编译
什么是预编译?
1、javascript是一种解释型语言,例如C、Java等强类型语言中的编译阶段,
它是没有这个步骤的,因此,javascript中有了类似于强类型语言编译阶段的步骤—预编译,
同时,我们需要知道,js引擎不是逐行的解释代码,而是按照代码块解释,
即,以标签为块,进行解释,
另外,我们还需要知道的是,预编译过程是在执行过程的前一刻发生并执行完毕,
也就是说到了执行阶段的时候,预编译的过程已经完成了;
2、我们在编程过程中有自己的一套语言和语法,同样的,计算机也有自己的一套,
面对代码,我们可以清晰的知道它的运行方式和顺序,但是,计算机不一定能懂,
因此,预编译也是让计算机“认识”我们所写的代码的过程,
例如下文将会提到的,AO对象,就是JS引擎在执行代码过程中重要的依赖;
初步了解预编译的过程
请同学们看下面代码:
test();
function test(){
console.log('a');
}
这个代码可以执行吗?
函数调用在函数定义的上方,这难道不报错?
不好意思,它可以执行,这就是预编译的功劳。
再看一个例子:
var a=123;
console.log('a');
这个结果应该是“123”没问题吧
那这样呐:
console.log('a');
var a=123;
这样也可以输出,但是结果却是“undefined”
为什么会出现这样的结果呐,这就不得不讲讲预编译中的重点AO对象
AO对象详细解答
首先,介绍一下预编译的四部:
1、创建AO对象
2、找形参和变量声明,将变量和形参作为AO属性名,值为undefined
3、将实参值和形参值统一
4、在函数体内找函数声明,值赋予函数体
看如下例子:
function fn(a){
console.log('a');
var a=123;
console.log('a');
function a(){}
console.log('a');
var b=function(){}
console.log('b');
function d(){}
}
fn(1);
//预编译发生在函数执行的前一刻
按照上述步骤,第一步创建AO Activation Object(执行期上下文)对象:
AO{
}
第二步:
AO{
a: undefined
b:undefined
}
第三步:
AO{
a:1
b:undefined
}
第四步:
AO{
a:function a (){}
b:undefined
d:function d(){}
}
其中 var b=function (){} 不是函数声明,它是函数表达式
到这里预编译过程完成,之后就按照函数体内,代码顺序,执行函数
其输出结果是
{
function a() {}
123
123
function (){}
}
GO对象:
1.生成GO对象GO{},这个GO就是window
2.将全局的变量声明储存到GO对象中,value为undefinde
3.将全局的函数声明的函数名作为GO对象中的key,函数整体内容为value储存到GO对象中
到此,对预编译过程是不是有一些初步了解呐?
如果还有不明白的地方,推荐学习渡一的js课程中的关于预编译这一节
本文中有部分资料参考于https://juejin.im/post/5cad8ff5e51d456e7618a681