JS预编译

JavaScript执行分为三个步骤:首先进行语法分析,看看代码是不是符合JS语法规范,然后要进行预编译,最后才开始解释执行;这个预编译的环节发生在函数执行的前一刻。

可以看到,在下面这个函数中,形参名、变量名、函数名很多都一样。那么每次console.log()出来的东西都是什么?只要了解了预编译,就会很清晰的知道。

function precompile(a){
				console.log(a);
				var a = 123;
				console.log(a);
				function a() {}
				console.log(a);
				var b = function () {}
				console.log(b);
				function c() {}
			}
			
			precompile(1);

在预编译过程中,首先根据这个名叫precompile的函数,创建了一个AO对象,也叫执行期上下文。然后开始在AO对象中赋值。这个过程按顺序又分为三个步骤:
1.找形参和变量声明,将变量和形参名作为AO属性名,默认值为undefined。
我们这个函数中,形参有一个,变量声明有两个,但因为形参名是a,其中一个变量声明也是a,所以AO对象中只能有一个a。

AO{
		a:undefined;
		b:undefined;
}

2.将实参值和形参统一
实参为1,所以根据规则AO中的a也应为1。

AO{
		a:1;
		b:undefined;
}

3.在函数体里面找函数声明,值赋予函数体
这里有函数a和c两个函数声明,所以a属性不需要重复添加,但是原来a的属性值1被覆盖为函数体。c属性因为没有出现过,所以要添加一个,属性值就是函数体。

AO{
		a:function a(){};
		b:undefined;
		c:function c(){};
}

到这里,预编译就完成了,然后根据预编译的结果开始执行函数,所以第一个打印的a的结果是function a(){},第二个打印a的结果是123,因为赋值了。第三个打印a的结果也是123。因为函数a声明已经被提升上去了。然后虽然AO中的b是undefined,但是又进行了赋值,所以console.log(b);是function () {}
在这里插入图片描述
预编译不只发生在函数中,全局中也会发生这一环节。比如:

console.log(a);
var a = 123;

这时我们console出来的a是undefined;那我们再在下面加上function a(){}

console.log(a);
var a = 123;
function a(){}

这时我们console出来的a会是function a(){};这就再次验证了预编译中的规则。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值