在一个执行环境中,会存在两个阶段:创建、执行。
例如有这么一段代码:
明显声明是在打印之后的,本应该报错,但这里打印的undefined告诉我们没有错误,存在x这个变量,只是没有赋值。
这就是变量提升的问题,这段代码位于一个函数执行环境中,因此就会有开头说到的两个阶段:创建、执行。
第一阶段:
第一个阶段是在函数调用之后,且函数体执行之前这段时间内。这时的Javascript解释器会扫描传递给函数的参数或arguments,本地函数声明和本地变量声明,在这个例子中会扫描到x这个变量,但仅仅只是这个变量,没有值(15)。
再继续看一个例子:
这个例子与上一个差不多,只是将变量x换成了一个函数声明。
我们看到上面的解释:
这时的Javascript解释器会扫描传递给函数的参数或arguments,本地函数声明和本地变量声明
也是在第一阶段中,解释器扫描到了这个func函数,但是与局部变量不同的是,函数体会直接赋给以func为名的属性。
第二阶段:
第二阶段会将局部变量的值赋给ExcutionContextObj对象中的同名属性,例如x=15。
此时是在函数体内部,那么在变量声明之后打印变量x就会正确输出15。