在JavaScript预编译过程中,let 和 const 定义的变量与 var 有几个关键区别。
变量提升
var:声明会被提升到作用域顶部,并初始化为undefined。let和const:声明也会被提升到作用域顶部,但不会初始化为undefined。在实际执行到声明语句之前,变量处于暂时性死区(Temporal Dead Zone, TDZ),访问会导致ReferenceError。
初始化和暂时性死区(TDZ)
-
var:在预编译阶段,变量会被提升并初始化为undefined。console.log(a); // 输出: undefined var a = 10; -
let和const:在预编译阶段,变量会被提升但不会初始化。在进入声明语句之前,变量处于暂时性死区(TDZ)。console.log(b); // ReferenceError: Cannot access 'b' before initialization let b = 10; console.log(c); // ReferenceError: Cannot access 'c' before initialization const c = 10;
作用域
-
var:函数作用域或全局作用域。声明的变量在整个函数或全局范围内可用,即使在块级代码(如if或for)中也是如此。if (true) { var d = 20; } console.log(d); // 输出: 20 -
let和const:块级作用域。变量仅在声明的块级代码内可用。if (true) { let e = 20; const f = 30; } console.log(e); // ReferenceError: e is not defined console.log(f); // ReferenceError: f is not defined
重复声明
-
var:允许在同一作用域内重复声明同一变量,但可能导致意外行为。var g = 10; var g = 20; console.log(g); // 输出: 20 -
let和const:不允许在同一作用域内重复声明同一变量,会导致语法错误。let h = 10; let h = 20; // SyntaxError: Identifier 'h' has already been declared const i = 10; const i = 20; // SyntaxError: Identifier 'i' has already been declared
总结
- 提升:
var声明的变量会被提升并初始化为undefined;let和const声明的变量会被提升但不会初始化。 - 暂时性死区(TDZ) :
let和const声明的变量在实际声明前不可访问,会导致ReferenceError。 - 作用域:
var是函数作用域或全局作用域;let和const是块级作用域。 - 重复声明:
var允许重复声明;let和const不允许在同一作用域内重复声明。