前言:声明提前经常出现在面试考题中,对理解JavaScript的机制有很大的帮助。
什么叫声明提前
在JavaScript中,函数所声明的变量在整个函数体都是有定义的;(包括函数体内嵌套的函数体)
这一特性可以形象地理解为声明的变量被提前到函数体顶部,被称作声明提前;
需要注意的是,变量的定义并没有被提前,而是留在原位置;
例如:
console.log(scope); //输出为undefined; 变量的定义没有被预解析
var scope = "global";
console.log(scope); //输出为global,说明变量的赋值仍在原位置
声明提前的原理:预解析
这涉及到JavaScript语言的预解析的特性,也就是说在代码执行前,浏览器会把var声明的变量和function声明的函数的内存空间预先解析出来以作用于其所在的作用域;(具体原理涉及到二者在内存空间的不同存储方式)。
二者的区别在于:
var声明的变量只会被解析变量的声明,变量的定义仍留在原处;
function声明的函数会被同时解析函数的声明和定义;
二者相同点:
都只作用于所处的作用域内;
例如:
console.log(f); //输出为函数的定义语块;函数的定义被预解析了
console.log(scope); //输出为undefined; 变量的定义没有被预解析
var scope = "global";
function f() {
console.log(scope); //将输出为undefined;局部变量的声明被预解析并覆盖了全局变量
var scope = "local"; //局部变量被赋值;
console.log(scope); //将输出为local;
}
总结:要掌握声明提前,重点在于理解作用域和预解析的概念;