郭减

前端开发工程师,前端爱好者

浏览器基础之变量提升 -- JavaScript 预解析

什么是“变量提升”

首先上个例子

1
2
3
console.log(a)
var a = 10
// undefined

上面这段代码估计大家都知道,打印的是undefined,因为js在加载的时候存在变量提升。上面的这段代码其实等同于这个:

1
2
3
var a;
console.log(a)
a = 10

再举一个例子大家看看

1
2
3
4
5
if(false){
var a = 10
}
console.log(a)
// undefined

我们可以发现,明明 if 语句里面的代码没有执行,但 a 的值依然是 undefined,说明预解析的过程并不受到 if 判断语句的影响

这就是变量提升导致的

  • 变量提升的原因:在当前作用域下,js运行之前,会把带有var和function关键字的事先声明,并在内存中安排好,这个过程叫做 预解析。然后再从上到下执行js语句。
  • 注意:预解析只会发生在通过var定义的变量和function上。

变量提升之 – var和function区别

刚刚提到了 “有varfunction关键字的事先声明”,那么 functionvar 都是变量提升,他俩在提升的时候,是并列的顺序往下提升呢,还是有一定的规则呢,我们看个例子

1
2
3
4
5
function add(){
console.log(2345)
}
var add;
console.log(add)

打印 add 之后发现了什么呢? 结果是 f add(){console.log(2345)} 还是 undefined 呢?大家可以自行将声明的顺序调换一下,发现打印的还是一样的结果

这其中就说明了两个问题

  1. js在预解析的时候, function 声明的变量,会覆盖 var 声明的变量
  2. function ,不但声明了变量,而且定义了变量的内容(因为刚刚的add打印的是 f add(){console.log(2345)} ,而不是 function(){}

拓展

let声明变量

1
2
console.log(a)
let a = 10

以上代码会报错 a is not defined ,说 a 未定义, let 是 ECMAScript 2015(es6)中声明变量的方式之一

说明 let 定义的变量,不存在变量提升,即 在哪定义变量,即在哪声明变量

测试题

试题如若不理解,请再次读一下预解析的定义:

在当前作用域下,js运行之前,会把带有var和function关键字的事先声明,并在内存中安排好,这个过程叫做 预解析。然后再从上到下执行js语句。

试题1

1
2
3
4
5
6
7
8
function add(){
var b;
console.log(a)
return;
function a(){
console.log(b)
}
}

试题2

1
2
3
console.log(a)
a = 10
// 不声明而直接使用的变量是全局变量
原创的技术分享,请我喝杯奶茶吧