JS 预编译

131 阅读2分钟

基础概要

javascript是解释性语言,主要特点为解释一行执行一行。 js完成解释执行分为三个步骤:1.语法分析;2.预编译(全局预编译、函数预编译);3.执行语句。

  • 语法分析会在代码执行前对代码进行通篇检查,以排除一些低级错误
  • 预编译发生在代码执行的前一刻
  • 执行语句就是执行代码

函数预编译

变量声明提升,function函数声明整体提升;发生在函数执行的前一刻(实际过程如下):

  1. 创建AO对象--Activation Object(执行期上下文):AO{ };
  2. 遇到变量声明, 变量名作为AO对象的属性名, 属性值置为 undefined
  3. 遇到形参, 形参名作为AO对象的属性名, 属性值置为 undefined
  4. 如果形参名与变量名冲突, 形参会将变量声明覆盖
  5. 将实参的值赋予形参, 即替换 AO对象中形参的属性值
  6. 遇到函数声明, 函数名作为AO对象的属性名, 属性值为函数本身
  7. 如果函数名与变量名冲突, 函数声明会将变量声明覆盖

解释执行

举例:

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);

//分析
(1) 创建AO对象--Activation Object(执行期上下文):
AO{ };

(2) 找形参和变量声明,将变量和形参名作为AO属性名,即变量提升过程,值为undefined;
AO {
	a:undefined,
	b:undefined
}

(3)将实参的值放到形参中去
AO {
	a:1,
	b:undefined
}

(4)在函数体里面找函数声明,值赋予函数体
从(a属性在AO对象中已存在,故只增加d属性):
AO {
	a:1,
	b:undefined,
	d:
}
到(给属性值赋予函数体):
AO{
	a:function a() {},
	b:undefined,
	d:function d() {}
}

全局预编译

”全局“即从页内js的script 的开始标签到结束标签,从页外js文件的第一行到最后一行。 全局预编译过程与函数预编译过程大致相似,只是全局上无形参、实参的概念。

  1. 生成一个GO对象--Global Object{},GO===window
  2. 变量提升
  3. 函数提升