前言
首先JavaScript这个预编译和传统的编译是不一样的(可以把js预编译理解为特殊的编译过程)
前面我们在讲JavaScript的作用域时提到了预编译,今天我就介绍一下预编译。 学好一门语言我们一定要知道该语言的运行机制。
JavaScript代码在运行时,首先会进行语法分析,通篇检查代码是否存在低级错误,然后进行预编译,整理内部的一个逻辑,最后再解释执行开始一行一行的执行代码
一. 语法分析
先全部扫一遍 看有没有语法错误,比如小括号(),花括号{}的缺失,或者是标点符号在中英文的状态下不对。
二. 预编译(执行前一刻)
变量 声明提升 函数声明整体提升。划重点,是变量声明和函数声明。
1、预编译前奏
-
暗示全局变量
任何变量,如果变量未经声明就赋值,此变量就为全局对象所有。
例如: a = 123;
上面的变量a 未经声明就赋值了,所以变量a是全局对象所有。
-
一切声明的全局变量,全是window的属性
例如:var a = 123; ===> window.a = 123
变量a是全局变量,所以也是window对象的属性。
2、预编译
函数中:预编译执行四部曲
- 创建AO对象 (Activation Object (执行期上下文))
- 找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
- 将实参值和形参统一
- 在函数体里面找函数声明,值赋予函数体
全局中:预编译三部曲
- 创建GO对象(Global Object window就是全局)
- 找变量声明,将变量声明作为GO对象的属性名,值赋予undifined
- 找全局里的函数声明,将函数名作为GO对象的属性名,值赋予函数体
三. 解释执行
预编译完成过后,解释一行执行一行
实例分析
<script>
var a = 1;
console.log(a);
function test(a) {
console.log(a);
var a = 123;
console.log(a);
function a() {}
console.log(a);
var b = function() {}
console.log(b);
function d() {}
}
var c = function (){
console.log("I at C function");
}
console.log(c);
test(2);
</script>
分析过程如下:
- 页面产生便创建GO全局对象(Global Object)(也就是window对象);
- 第一个脚本文件加载;
- 脚本加载完毕后,分析语法是否合法;
- 开始预编译
- 查找变量声明,作为GO属性,值赋予undefined;
- 查找函数声明,作为GO属性,值赋予函数体;
- 在预编译过程中,变量声明出现同名不覆盖,变量声明与函数声明同名,变量声明不能覆盖函数声明,函数声明直接覆盖变量声明,值为函数体。
全局预编译结束后,GO中存储的值
如下所示:
GO/window = {
a: undefined,
c: undefined,
test: function(a) {
console.log(a);
var a = 123;
console.log(a);
function a() {}
console.log(a);
var b = function() {}
console.log(b);
function d() {}
}
}
解释执行代码(直到执行完test(2)语句)
GO/window = {
a: 1,
c: function (){
console.log("I at C function");
}
test: function(a) {
console.log(a);
var a = 123;
console.log(a);
function a() {}
console.log(a);
var b = function() {}
console.log(b);
function d() {}
}
}
执行函数test()之前,再次发生预编译,(此时是函数体执行之前产生的AO对象)
预编译第一和第二两小步如下:
AO = {
a:undefined,
b:undefined,
}
预编译之第3步如下:
AO = {
a:123,
b:undefined,
}
预编译之第4步如下:
AO = {
a:function a() {},
b:undefined
d:function d() {}
}
执行test()函数时如下过程变化:
AO = {
a:function a() {},
b:undefined
d:function d() {}
}
--->
AO = {
a:123,
b:undefined
d:function d() {}
}
--->
AO = {
a:123,
b:function() {}
d:function d() {}
}
最后的执行结果 :
1
fn:c
fn:a
123
123
fn:b
文章是笔者分享的学习笔记,若你觉得可以、还行、过得去、甚至不太差的话,可以“推荐”一下的哦。就此谢过!