Javascript的var, let和const
在 ES6 之前,JavaScript 只有 var
关键字来声明变量,这导致了一些难以管理的问题,如变量提升、作用域混乱、不可预测的值等。为了改善这些问题,ES6 引入了 let
和 const
,提供了更清晰的变量作用域和更严格的使用规则。
let
和 const
的工作原理
-
块级作用域(Block Scope):
let
和const
声明的变量具有块级作用域,即它们的作用范围是当前的代码块(用花括号{}
包裹的代码)。- 这与
var
的函数作用域不同,var
的作用域是函数内部,即使声明在块中,仍然是全局或函数作用域。
{ let x = 10; var y = 20; } console.log(x); // Uncaught ReferenceError: x is not defined console.log(y); // 20
-
不提升声明(No Hoisting in the Same Way as
var
):let
和const
变量在声明之前无法访问,它们被认为在声明前处于“暂时性死区(Temporal Dead Zone,TDZ)”。而var
则会被提升,可以在声明前访问(但值是undefined
)。
console.log(a); // undefined var a = 5; console.log(b); // Uncaught ReferenceError: Cannot access 'b' before initialization let b = 6;
-
const
的特性:const
用于声明常量。声明后,其引用不能改变,但对于对象和数组,内部值是可以变更的(因为const
仅保证引用地址不变)。const
变量必须在声明时初始化,且不能再次赋值。
const c = 10; c = 15; // Uncaught TypeError: Assignment to constant variable. const obj = { name: 'Alice' }; obj.name = 'Bob'; // 允许,因为改变的是对象的属性,而不是引用
-
防止重复声明:
let
和const
不允许在同一作用域内重复声明相同名称的变量,避免了var
导致的覆盖问题。
let x = 10; let x = 20; // Uncaught SyntaxError: Identifier 'x' has already been declared var y = 10; var y = 20; // 允许
let
和 const
的运行机制
-
作用域绑定:
let
和const
的变量绑定在其所在的块级作用域中,使得 JavaScript 在编译阶段就确定了变量的作用域边界。 -
TDZ(暂时性死区):在块级作用域中,当代码进入该作用域直到变量声明完成之前,这个变量处于 TDZ 中,无法访问。访问此时的变量会抛出引用错误。
-
垃圾回收:因为
let
和const
在块结束时会被销毁,这有助于 JavaScript 引擎更好地进行内存管理。
总结
let
和 const
是 ES6 为了解决传统 var
声明问题而引入的,提供了更严格和安全的变量声明机制。它们通过块级作用域、TDZ 和不允许重复声明的规则,使得代码更易于理解、调试和维护。这些关键字的引入是 JavaScript 语言朝现代化编程发展的重要一步。