什么是“变量提升”
首先上个例子
1 | console.log(a) |
上面这段代码估计大家都知道,打印的是undefined,因为js在加载的时候存在变量提升。上面的这段代码其实等同于这个:
1 | var a; |
再举一个例子大家看看
1 | if(false){ |
我们可以发现,明明 if
语句里面的代码没有执行,但 a
的值依然是 undefined
,说明预解析的过程并不受到 if
判断语句的影响
这就是变量提升导致的
- 变量提升的原因:在当前作用域下,js运行之前,会把带有var和function关键字的事先声明,并在内存中安排好,这个过程叫做 预解析。然后再从上到下执行js语句。
- 注意:预解析只会发生在通过
var
定义的变量和function
上。
变量提升之 – var和function区别
刚刚提到了 “有var
和function
关键字的事先声明”,那么 function
和 var
都是变量提升,他俩在提升的时候,是并列的顺序往下提升呢,还是有一定的规则呢,我们看个例子
1 | function add(){ |
打印 add
之后发现了什么呢? 结果是 f add(){console.log(2345)}
还是 undefined
呢?大家可以自行将声明的顺序调换一下,发现打印的还是一样的结果
这其中就说明了两个问题
- js在预解析的时候,
function
声明的变量,会覆盖var
声明的变量 function
,不但声明了变量,而且定义了变量的内容(因为刚刚的add打印的是f add(){console.log(2345)}
,而不是function(){}
)
拓展
let声明变量
1 | console.log(a) |
以上代码会报错 a is not defined
,说 a
未定义, let
是 ECMAScript 2015(es6)中声明变量的方式之一
说明 let
定义的变量,不存在变量提升,即 在哪定义变量,即在哪声明变量
测试题
试题如若不理解,请再次读一下预解析的定义:
在当前作用域下,js运行之前,会把带有var和function关键字的事先声明,并在内存中安排好,这个过程叫做 预解析。然后再从上到下执行js语句。
试题1
1 | function add(){ |
试题2
1 | console.log(a) |