js代码在执行前,会有一个预处理的步骤,看代码
alert(a)
alert(b)
alert(c)
alert(d)
var a = 1;
b = 2;
alert(b)
function c() {}
d = function() {}
alert(d)
运行上述代码,结果分别是(调试的时候可以注释掉报错的语句)
- undefined
- 程序报错
- "function(){}"
- 程序报错
- 2
- "function(){}"
现在来分析一下,js的预处理是什么意思呢? js代码运行前,js解析器,首先会把var 开头的变量,和声明式定义的函数,放到一个词法环境中 以上述代码为例,js的词法环境是这样的
{
a : undefined,
c : 指向函数的引用
}
可以看到,解析器会忽略非var定义的变量和函数表达式,那如果存在重名的情况是则么样的呢? 假设
function a () {};
var a = 100;
在js中,函数是一等公民,所以这种情况下,词法环境是这样的
{
a : 指向函数的引用
}
ok,然后开始正式执行最上面的代码。 当执行到b = 2
的时候
{
a : 1,
b : 2,
c: 指向函数的引用
}
词法环境发生了改变, 所以这时候b能打印出来了。d和b同理。