# NO.1
```
var c = 1;
function c(c) {
console.log(c);
var c = 3;
}
c(2)
```
## 技術點:
1.變量提升 2.函數提升 3.預處理 4.調用順序**
## 陷阱
全局變量名、函數名、函數形參都是`c`**
## 結果

## 分析
看到這結果有沒有大吃一驚?
我們現在來分析下原因。
這里我們先來了解下“預處理”,那什么是預處理呢?js語言本身具有預處理機制,js引擎在預處理期對所有聲明的變量和函數進行處理,就是先把變量進行聲明并讀到內存里。也就是收集用var聲明的變量信息和函數聲明信息
還有一點是預處理時,變量和函數的優先順序,先變量后函數。當變量名和函數名一致時后者會覆蓋前者,我們看下下面的小案例:
```
function b() {}
var b
console.log(typeof b)
```
結果為function,這就證實了,我們剛才的結論,執行順序先變量后函數,變量名一致時,函數就會覆蓋變量。
再來說一下預處理,看一下下面的小案例:
```
var a = 2
function fn() {
console.log(a)
var a = 3
}
fn()
```
運行下,結果為undefined。
為什么為undefined呢?因為這里預處理順序是這樣的,外面聲明了個全局變量a,值為2,但是里面把a聲明成了局部變量,函數內部的預處理順序為先聲明var a;然后console.log(a);最后a=3;所以我們調用函數的時候,里面是有a,所以不會調外面的全局a,只是里面的a暫時還沒有值,因為a=3這賦值步驟是在console.log(a)后面執行的,所以我們運行時就看到undefined了。拓展下,如果函數里面去掉var,那么打印出來的值就是2了,然后全局變量a又被賦值為3。
那好,我們現在回到我們剛才的題目上來,剛才題目的解析順序可以理解為以下步驟:
1. 首先預處理 `var c`
2. 然后預處理整個c函數
```
function c(c) {
console.log(c);
var c = 3;
}
```
此時`c`的`typeof`為`function`
3. 接著給`c`賦值為`1`,即 `c=1`
此時`c`是整型變量`1`。`typeof`為`number`了
4. 最后再執行`c(2)`調用函數
所以我們調用的時候當然就會報`c`不是一個函數的錯誤了,因為他現在是一個整型變量了啊,哈哈,是不是很傷腦筋啊……
# NO.2
```
var a = 6
setTimeout(function () {
console.log(0)
alert(a)
a = 666
}, 0)
console.log(1)
a = 66
```
## 技術點
定時器、意外全局變量、作用于與作用域鏈、變量查找、事件循環
## 結果
1 0 66
## 分析
按照先執行同步代碼原則,即使setTimeout的時間是0甚至是不傳時間,setTimeout仍然是異步代碼
* 首先輸出:1
* 然后將66賦值給全局變量a,此時全局變量a = 66
* 接著執行異步setTimeout中的代碼,輸出:0
* 最后彈出變量a,此時變量a的值是66