let、const和var的区别是什么?解释暂时性死区(TDZ)

在 JavaScript 中,varletconst 是三种变量声明方式,它们在作用域、变量提升、重复声明等行为上有显著区别,同时 letconst 引入了 暂时性死区(Temporal Dead Zone, TDZ) 的概念。以下是详细对比和解析:


一、核心区别对比

特性 var let const
作用域 函数作用域或全局作用域 块级作用域({} 内有效) 块级作用域({} 内有效)
变量提升 ✅ 提升且初始化为 undefined ✅ 提升但未初始化(TDZ 限制) ✅ 提升但未初始化(TDZ 限制)
重复声明 ✅ 允许 ❌ 禁止 ❌ 禁止
声明时初始化 ❌ 可先声明后赋值 ❌ 可先声明后赋值 ✅ 必须声明时赋值
重新赋值 ✅ 允许 ✅ 允许 ❌ 禁止(对象属性可修改)

二、作用域差异

1. var:函数作用域
function exampleVar() {
  if (true) {
    var a = 10;
  }
  console.log(a); // 10(变量泄露到函数作用域)
}
2. let/const:块级作用域
function exampleLet() {
  if (true) {
    let b = 20;
    const c = 30;
  }
  console.log(b); // ReferenceError: b未定义
  console.log(c); // ReferenceError: c未定义
}

三、变量提升与暂时性死区(TDZ)

1. var 的变量提升

变量提升(Hoisting)指在代码执行前,声明会被提升到作用域顶部,但 var 变量初始化为 undefined

console.log(x); // undefined(不会报错)
var x = 5;
2. let/const 的暂时性死区(TDZ)

虽然 letconst 也会提升,但在声明前访问会触发 TDZ,导致报错:

console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 10;

TDZ 的表现
从进入作用域到变量声明语句执行之前,访问变量会报错:

{
  // TDZ 开始(变量 y 不可访问)
  console.log(y); // ❌ ReferenceError
  let y = 20;     // TDZ 结束
}

四、重复声明与重新赋值

1. 重复声明
var a = 1;
var a = 2; // ✅ 允许

let b = 3;
let b = 4; // ❌ SyntaxError: Identifier 'b' has already been declared
2. 重新赋值
const PI = 3.14;
PI = 3.1415; // ❌ TypeError: Assignment to constant variable

const obj = { value: 1 };
obj.value = 2; // ✅ 允许(对象属性可修改)

五、使用场景建议

声明方式 适用场景
var 旧代码维护、需要函数作用域的少数场景(不推荐新项目使用)
let 需要重新赋值的变量(如循环计数器、动态更新的状态)
const 常量(如配置项、函数表达式)、对象/数组引用(确保引用不变,内容可修改)

六、总结

  1. 作用域var 是函数作用域,let/const 是块级作用域。
  2. 变量提升:三者均会提升,但 var 会初始化为 undefined,而 let/const 在 TDZ 内不可访问。
  3. TDZlet/const 在声明前访问会报错,强制开发者先声明后使用。
  4. 最佳实践
    • 默认使用 const(除非需要重新赋值)。
    • 需要重新赋值时用 let
    • 避免使用 var(防止变量污染和意外覆盖)。

你可能感兴趣的:(面试-技术试炼场,筑基篇-原生三剑客,前端,javascript,面试)