# NO.1
```
var c = 1;
function c(c) {
console.log(c);
var c = 3;
}
c(2)
```
## 技术点:
1.变量提升 2.函数提升 3.预处理 4.调用顺序**
## 陷阱
全局变量名、函数名、函数形参都是`c`**
## 结果
![](https://box.kancloud.cn/04d0bce3c1a3555d18b8160c65faba6f_217x27.png)
## 分析
看到这结果有没有大吃一惊?
我们现在来分析下原因。
这里我们先来了解下“预处理”,那什么是预处理呢?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