来看一个有趣的例子:

var fish = 1;

function bear(){

   fish = 2;

   return;

   function fish(){};

}

bear();

console.log(fish);

这里运行的结果是1。

可能会有人疑惑为什么是1不是2呢(^-^),这也是我最开始疑惑的。

我们可以试试如果在fish=2这行代码之后加上console.log(fish)会怎么样:

var fish = 1;

function bear(){

   fish = 2;

   console.log(fish);

   return;

   function fish(){};

}

bear();

得到的结果为2。

也就是说在bear()函数返回之前fish的值为2,函数返回之后fish的值就变为1了,那么这中间发生了什么呢?

其实,javascript预解析的时候会发生变量和函数的声明提升,字面上讲就是在当前作用域下将变量和函数的声明提到最前面,事实上,变量和函数的声明在代码中的位置并不会发生改变,而是在编译阶段被放入内存中。

为了理解,现在我们先把全局作用域下的函数和变量声明提升:

var fish;

function bear(){

   fish = 2;

   return;

   function fish(){};

}

fish = 1;

bear();

console.log(fish);

然后把bear()函数中的fish函数声明提升:

var fish;

function bear(){

   function fish(){};

   fish = 2;

   return;

}

fish = 1;

bear();

console.log(fish);

现在答案已经清晰了,因为在最后一行的console.log(fish)中的fish是指的全局作用域中的变量fish,而bear函数中的fish其实是指在bear函数局部作用域中fish函数,即使将其赋值为2也与全局作用域中的fish无关了。