JavaScript 变量提升(Hoisting)

226 阅读1分钟

概述

我们经常看到的声明

var a = 1;

在Javascript中,实际上是两个操作(声明、赋值),在编译阶段会把代码变成

var a;
a = 1;

在(预)编译阶段,解释器会把作用域中的所有声明放在作用域最顶端(这仅仅是在内>存中表现出来的结果,并不改变代码本身结构或顺序),而赋值行为则不做变动。 而上述现象就是变量提升。

行为

1. 仅提升声明,不提升赋值(初始值为undefined);

console.log(a); // undefined
var a = 1;

// 相当于
var a;
console.log(a);
a = 1;

2. 函数提升会因函数声明方式产生不一样的效果;

// 函数声明式
// 函数名和函数体都会被提升
console.log(foo);
// ƒ foo () {
//  console.log(1);
// }
function foo () {
  console.log(1);
}

// 相当于
function foo () {
  console.log(1);
}
console.log(foo);
// 函数表达式
// 仅提升变量,匿名函数体不会被提升(与变量提升一致)
console.log(foo); // undefined
var foo = function () {
  console.log(1);
}

// 相当于
var foo;
console.log(foo);
foo = function () {
  console.log(1);
}

注意项

1. let、const等声明不存在变量提升现象(因此let、const存在暂时性死区); 2. 变量重复声明,不会重复提升; 3. 函数提升在变量提升之后(如下);

console.log(foo);
// ƒ foo () {
//   console.log(1);
// }
function foo () {
  console.log(1);
}
var foo = 1;
console.log(foo); // 1

// 相当于
var foo;
function foo () {
  console.log(1);
}
console.log(foo);
// ƒ foo () {
//   console.log(1);
// }
foo = 1;
console.log(foo); // 1

以上是个人对变量提升的理解,如有错误处,希望大家多多包涵并指正。