最近,在读《你不知道的JavaScript(上卷)》这本书,书中详细阐述了JavaScript众多重要但经常被大家忽略的点,在此强烈推荐!!!书中,第4章讲述了“提升”,从示例出发讲述了变量和函数提升的过程,纠正了自己以前错误的理解(相信好多人理解都是错误)!
我们习惯将var a = 2;看做一个声明,而实际上JavaScript引擎不这么认为!下面几个示例让你彻底搞懂JavaScript中的变量提升!
示例1:
~~~
a = 2;
var a ;
console.log(a); //2
~~~
示例2:
~~~
console.log(b); //undefined
var b = 2;
~~~
示例3:
~~~
var c;
console.log(c); //undefined
c = 2;
~~~
示例4:
~~~
foo();
function foo(){
console.log(d); //undefined
var d = 2;
}
~~~
示例5:
~~~
bar(); //TypeError
var bar = function too(){
// ....
}
~~~
示例6:
~~~
aoo(); //TypeError
boo(); //ReferenceError
var aoo = function boo(){
// ...
}
~~~
示例7:
~~~
function foo(){
console.log(1);
}
foo(); //1
foo = function(){
console.log(2);
};
~~~
示例8:
~~~
foo(); //3
function foo(){
console.log(1);
}
var foo = function(){
console.log(2);
};
function foo(){
console.log(3);
}
~~~
示例9:
~~~
foo(); //b
var a = true;
if(a){
function foo(){ console.log("a"); }
}else{
function foo(){ console.log("b"); }
}
~~~
**总结:**
1. var a = 2;其中var a在编译阶段,a=2在执行阶段;
2. 无论作用域中的声明(变量和函数)出现在什么地方,都将在代码本身执行前首先进行处理;
3. 声明本身会被提升,而包括函数表达式的赋值在内的赋值操作并不会提升;
4. 函数会首先被提升,然后才是变量,重复的var(变量)声明会被忽略掉;
5. 后面的函数声明可以覆盖前面的。
**PS:**
1. RHS查询在所有嵌套的作用域中遍寻不到所需遍历会抛出ReferenceError。
2. RHS查询到一个变量,但你尝试对其不合理的操作(引用null或undefined类型中的属性),会抛出TypeError。