我们习惯将var a = 2;看作一个声明,而实际上JavaScript引擎并不这么认为。
它将var a和a = 2当作两个单独的声明,第一个是编译阶段的任务,而第二个则是执行阶段的任务。
编译阶段中的一部分工作就是找到所有的声明,并用合适的作用域将它们关联起来。包括变量和函数在内的所有声明都会在任何代码被执行前首先被处理。
这个代码片段经过提升后,实际上会被理解为以下形式:
函数声明和变量声明都会被提升。但是函数会首先被提升,然后才是变量。
重复的var声明会被忽略掉
会输出1而不是2!这个代码片段会被引擎理解为如下形式:
var foo尽管出现在function foo()...的声明之前,但它是重复的声明(因此被忽略了),因为函数声明会被提升到普通变量之前。
出现在后面的函数声明可以覆盖前面的
说明了在同一个作用域中进行重复定义是非常糟糕的,而且经常会导致各种奇怪的问题。
一个普通块内部的函数声明通常会被提升到所在作用域的顶部,这个过程不会像下面的代码暗示的那样可以被条件判断所控制:
因此应该尽可能避免在块内部声明函数。