针对ES5。预处理阶段涉及到(var关键字声明的,包括函数表达式)变量和(以function关键字声明的)函数的声明提前,并且还涉及到声明变量冲突的时候的解决方式。
声明提前
将变量保存到window域中,会扫描用var操作符声明的变量、以及用function关键字声明的函数指针,因此会产生变量和函数声明提前的效果。
观察下面的代码。
var a = 1;
b = 2;
function f(){ console.log('11');}
var g = function(){ console.log('22'); };
在预处理阶段,window域的情况如下
window{
f: 指向函数的指针,
a: undefined,
g: undefined
} //演示,非准确情况
在执行到对应语句的时候,情况如下
window {
f: 指向函数的指针,
a: 1,
b: 2,
g: 指向函数的指针
}
需要说明的是:
- 如果变量并没有用var声明,如b = 1;那么虽然在执行阶段将其默认为全局变量,在预处理阶段也不会将其添加到window域中。实际上,直到执行到这一条语句的时候,才会将其添加。
- 函数表达式用var声明,处理方式与用var声明的其他变量一样。
如果变量并没有用var声明,如b = 1;那么即使在函数执行阶段将其默认为全局变量,在预处理阶段也不会将其添加到window域中。直到执行到这一条语句的时候,才会将其和对应的值添加。
函数表达式用var声明,所以处理方式与用var声明的其他变量一样。
声明冲突
如果声明发生冲突,那么在预处理的时候遵循两个规则:
- 先扫描函数,再扫描var声明的变量
- 如果与之前的声明发生冲突的是函数,则覆盖
- 如果与之前的声明发生冲突的是用var声明的变量,则忽略。
举例如下
alert(f);
function f(){ console.log('11');}
var f = 1;
显然alert为"function f(){console.log('11');}"
网友评论