var 声明与变量提升
使用 var 关键字声明的变量,无论其实际声明位置在何处,都会被视为声明于所在函数的顶部(如果声明不在任意函数内,则视为在全局作用域的顶部)。这就是所谓的变量提升(hoisting)。为了说明变量提升的含义,请参考如下函数定义:
function getValue(condition) {
if (condition) {
var value = "blue";
// 其他代码
return value;
} else {
// value 在此处可访问, 值为 undefined
console.log(value)
return null;
}
// value 在此处可访问, 值为 undefined
}
getValue(false) // 输出undefined
如果你不太熟悉 JS,或许会认为仅当 condition 的值为 true 时,变量 value 才会被创建。但实际上,value 无论如何都会被创建。JS 引擎在后台对 getValue 函数进行了调整,就像这样:
function getValue(condition) {
var value;
if (condition) {
value = "blue";
// 其他代码
return value;
} else {
console.log(value)
return null;
}
}
value 变量的声明被提升到了函数作用域顶部,而初始化工作则保留在原处。这意味着在 else 分支内 value 变量也是可访问的,此处它的值会是 undefined,因为它并没有被初始化。
JS 的初学者经常需要花点时间才能习惯变量提升,而如果不理解这种特有行为,就可能导致 bug。正因为如此,ES6 引入了块级作用域,让变量的生命周期更加可控。