你不知道的js—变量提升

441 阅读1分钟

变量提升

先有鸡还是先有蛋

打印的结果是2,声明a在赋值之后,为什么打印a,结果会是2呢?

a = 2;
var a;
console.log(a); 

编译器再度来袭

var声明变量会发生变量提升,编译器在出来上述代码时,会编译成:

var a;
a = 2;
console.log(a); 

这样打印出2就很合理了,也就说明是先有蛋(声明),后有鸡(赋值)

每个作用域都会进行变量提升

下面代码执行结果:foo中打印结果是2。最后执行的打印会报错。

因为每个作用域中都有自己的变量提升

function foo() {
    a = 2;
    var a;
    console.log(a)
}
foo();
console.log(a)

函数也会提升

会发现代码可以正常执行,函数可以先使用,后声明,也就意味着函数声明是可以提升的。

foo();
function foo() {
    console.log(2)
}

函数表达时不能提升 会报错foo不是一个函数,因为下面的foo不是函数声明,只是一个函数表达式。具体函数声明和函数表达式的区别,大家可以去看juejin.cn/post/704084… ,后者自己找文章阅读。

foo();
var foo = function() {
    console.log(2)
}

函数优先

下面代码执行结果:第一打印aa函数,第二个打印2。为什么?

function aa() {}
console.log(aa)
var aa = 2;
console.log(aa)

首先上面的代码会编译成:

function aa() {};
var aa;
console.log(aa)
aa = 2;
console.log(aa)

var声明和函数声明在一起时,会遵循函数优先的原则,所以第一个console打印函数aa,然后重新给aa复制为2,第二次console打印出2。

let、const不会提升

下面的代码会报错,因为let、const不会发生变量提升。

console.log(a)
let a = 2

console.log(b)
const b = 2