#### 聲明提升
```
a = 2;
var a;
console.log(a); //2
//等同于
var a;
a = 2;
console.log(a);
```
```
console.log(a); //undefined
var a = 2;
//等同于
var a;
console.log(a);
a = 2;
```
var a = 2其實在解析的時候被拆成了兩個聲明:var a和a = 2,第一個是在編譯階段執行的,稱為定義聲明;第二個是在執行階段執行的,稱為賦值聲明。
普通變量、函數聲明會被提升,而函數表達式不會被提升。
```
foo(); //會執行,只不過輸出結果是undefined
function foo(){
console.log(a); //undefined
var a = 2;
}
//等同于
function foo(){
var a;
console.log(a);
a = 2;
}
foo();
```
```
//undefined(),拋出TypeError異常
foo(); //TypeError
var foo = function (){...}
```
即使是具名的函數表達式也不可以
```
foo();
bar();
var foo = function bar(){...}
//等同于
var foo;
foo();//TypeError
bar();//ReferenceError
foo = function (){var bar = ...self...}
```
#### 提升順序
函數聲明和變量聲明都會被提升,但是函數會首先被提升,然后才是變量。
```
foo();
var foo;
function foo(){console.log(1)}
foo = function(){console.log(2)}
//等同于
function foo(){console.log(1)}
foo();
foo = function(){console.log(2)}
```
由于function foo被提升到了最前面,后面的foo聲明被認為是重復的聲明,被舍去,所以var foo就不存在了。因此要避免重復聲明,特別是當var和函數聲明混在一起時不要使用相同的變量名,會引起很多危險的問題。
- 你不知道的JS上
- 第一部分 第三章 函數作用域和塊作用域
- 第一部分 第四章 提升
- 第一部分 第五章 閉包
- 第二部分 第一章 關于this
- 第二部分 第二章 this全面解析
- 第二部分 第三章 對象
- 第二部分 第五章 原型
- 第二部分 第六章 行為委托
- 你不知道的JS中
- 第一部分 第二章 值
- 第一部分 第三章 原生函數
- 第一部分 第四章 強制類型轉換
- 第一部分 第五章 語法
- 第二部分 第一章 異步
- 第二部分 第三章 Promise
- 第二部分 第四章 生成器
- 第二部分 第五章 性能
- 你不知道的JS下
- 第一部分 總結
- 第二部分 第二章 語法
- 第二部分 第三章 代碼組織
- 第二部分 第四章 Promise
- 第二部分 第五章 集合
- 第二部分 第六章 新增API
- 第二部分 第七章 元編程
- 第二部分 第八章 ES6之后