var / let / const 区别

解释 JavaScript 中 var、let、const 在作用域、变量提升、暂时性死区和重新赋值方面的核心差异。

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

[!info] related notes

var / let / const 区别

这篇笔记回答一个问题:var、let、const 在 JavaScript 中到底差在哪。

一句话定义

var 是函数作用域且存在变量提升,let 和 const 是块级作用域且存在暂时性死区,const 额外要求不能重新绑定。

核心差异

维度varletconst
作用域函数作用域块级作用域块级作用域
变量提升是(初始值为 undefined)是(但进入暂时性死区)是(但进入暂时性死区)
暂时性死区
重新赋值允许允许不允许
重复声明允许不允许不允许

核心机制

变量提升

var 声明会在编译阶段被提升到函数顶部,未赋值前访问得到 undefined。

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

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

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

暂时性死区

从块开始到 let / const 声明语句之间的区域称为暂时性死区。这段时间内变量已存在但不能访问。

if (true) {
  // TDZ 开始
  console.log(x); // ReferenceError
  let x = 1; // TDZ 结束
}

块级作用域

let / const 只在最近的 {} 内有效,var 会逃逸到函数级别。

for (var i = 0; i < 3; i++) {}
console.log(i); // 3,var 逃逸

for (let j = 0; j < 3; j++) {}
console.log(j); // ReferenceError,let 不逃逸

const 的不可重新绑定

const 不允许改变绑定本身,但如果值是对象或数组,内部属性仍可修改。

const obj = { a: 1 };
obj.a = 2;    // 可以
obj = {};     // TypeError: 不能重新赋值

常见误解

  • “let / const 不会提升” -> 错误,它们会提升,只是进入 TDZ
  • “const 声明的值完全不可变” -> 错误,只是绑定不可变,对象属性可变
  • “var 只有全局和函数两个作用域” -> 正确,没有块级作用域

最小例子

// var: 函数作用域,提升为 undefined
function testVar() {
  console.log(x); // undefined
  var x = 1;
}

// let: 块级作用域,TDZ
function testLet() {
  // console.log(y); // ReferenceError
  let y = 1;
}

// const: 块级作用域,不可重绑
function testConst() {
  const z = 1;
  // z = 2; // TypeError
}
创建于 2026/4/3 更新于 2026/5/27