自由变量
概念: 当前作用域没有定义的变量
变量提升
1.JS代码执行顺序
我们直觉上会认为JS的代码在执行时是由上到下一行一行执行的,但实际并不完全正确,下面的例子会证明:
a = 'haha'
var a
console.log(a)
上面的代码会输出什么呢?
如果按照我们认为的由上到下一行一行执行,那么应该输出undefined,但是实际结果是’haha’。
接着再看一个代码:
console.log(a)
var a = 'haha'
那这个输出的是什么?
鉴于上面代码表现出来的非自上而下的特点,有可能认为是’haha’。或者有认为变量a没有声明,所以会报错,但实际结果是undefined
为什么会是这样呢?到底发生什么?让我们带着这个问题看下去
2.变量提升
2.1 编译
我们要知道,引擎在解释JS代码之前首先要对代码进行编译,在编译阶段中有一部分工作就是找到所有的声明,并用合适的作用域将他们关联起来。
JS执行的流程图大致如下:
所以总结来说,包括变量和函数在内的所有声明在编译阶段都会首先被处理,然后才是代码被执行的阶段。
当我们看到var a = 'haha’时候认为它是一个声明,但其实在JS中它会被看做两个声明,var a和a = ‘haha’。var a是定义声明,是在编译阶段进行;a = 'haha’是赋值声明,会留在原地等待执行阶段。
2.2 解释上面问题
接着我们再看回第一个例子:
a = 'haha'
var a
console.log(a)
通过上面说明,可以知道会先处理定义声明,所以整个代码会以如下形式进行处理:
var a //在编译阶段进行变量提升
a = 'haha'
console.log(a)
第二个例子也是相同处理
console.log(a)
var a = 'haha'
在这个例子中也会进行变量提升,所以整个代码会以如下形式进行处理:
var a
console.log(a)
a = 'haha'