变量提升

解释 JavaScript 变量提升机制,包括 var 声明提升、函数声明提升和 let/const 暂时性死区。

#tech / dev / frontend #type / concept #status / growing #resource / javascript #resource / ecmascript

[!info] related notes

变量提升

这篇笔记回答一个问题:JavaScript 中的变量和函数声明为什么可以在声明之前访问。

一句话定义

变量提升是指 JavaScript 引擎在编译阶段将变量和函数声明移动到当前作用域顶部的行为。

核心机制

变量声明提升

var 声明会被提升到函数或全局作用域顶部,但赋值不会提升。

console.log(a); // undefined(不是 ReferenceError)
var a = 1;
// 等价于:
// var a;
// console.log(a);
// a = 1;

函数声明提升

函数声明(function fn() {})整体提升,包括函数体,可以在声明前调用。

fn(); // "hello"
function fn() {
  console.log('hello');
}

函数表达式不提升函数体

函数表达式只提升变量声明,不提升赋值。

fn(); // TypeError: fn is not a function
var fn = function() {
  console.log('hello');
};

let / const 的暂时性死区

let 和 const 也会提升,但进入暂时性死区(TDZ),在声明前访问会抛 ReferenceError。

console.log(b); // ReferenceError
let b = 1;

优先级

当 var 和函数声明同名时,函数声明优先。

console.log(typeof fn); // "function"
var fn = 1;
function fn() {}

常见误解

  • “变量提升是把代码物理移动了” -> 错误,是引擎在编译阶段的行为,源码不变
  • “let / const 没有提升” -> 错误,它们有提升,只是进入 TDZ
  • “只有 var 会提升” -> 错误,函数声明也会提升,而且优先级更高

最小例子

// 1. var 提升
console.log(x); // undefined
var x = 10;

// 2. 函数声明提升
sayHi(); // "hi"
function sayHi() { console.log('hi'); }

// 3. 函数表达式不提升
// greet(); // TypeError
var greet = function() { console.log('greet'); };

// 4. let TDZ
// console.log(y); // ReferenceError
let y = 20;
创建于 2026/4/3 更新于 2026/5/27