ECMAScript 中 var、let、const 的区别与常见问题详解
本文详解 ECMAScript 中 var、let 和 const 三大声明关键字的核心区别。重点解析函数作用域与块级作用域的差异,阐述 const 必须初始化的特性,深入剖析变量提升机制及暂时性死区概念,并通过代码示例说明全局对象属性挂载及循环中的变量行为,帮助开发者规范代码并避免常见错误。
引言
在 ECMAScript 规范中,提供了三个用于声明变量的关键字:var、let 和 const。其中,var 关键字在所有 ECMAScript 版本中均被支持;而 let 和 const 则是 ECMAScript 6(ES6)及更高版本中引入的特性,需在兼容 ES6 的环境中才能使用。
let 和 const 在行为上高度相似,但存在一个关键区别:使用 const 声明变量时,必须同时完成初始化操作。若尝试修改由 const 声明的变量,程序将抛出运行时错误。因此,开发者通常将 const 用于声明常量。
一:作用域
var 关键字定义的是函数作用域。
let 和 const 关键字定义的是块级作用域。
这意味着,由 var 声明的变量在离开其所在的函数体时才会被销毁;而由 let 和 const 声明的变量,在离开其所在的代码块(如 if、for 或 {} 包围的区域)时即被销毁。
以下通过 for 循环示例进行说明:
for 循环中的变量声明方式,体现了 var 和 let 的重要差异。
for (var i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i);
}, 0);
} //5 5 5 5 5
for (var i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i);
}, 0);
} //0 1 2 3 4
造成上述现象的原因在于:var 声明的变量可以穿透循环体外部,当循环退出时,迭代变量保留的是导致循环终止的那个值。相比之下,let 的作用域被限制在 for 循环的代码块内部,每次迭代都会声明一个新的变量实例,因此每个 setTimeout 回调引用的都是各自独立的变量副本。
二:优先级
这三个关键字之间不存在优先级高低之分,变量的可见性严格遵循代码中的声明顺序。
三:全局声明区别
let 与 var 在全局作用域下的行为不同:使用 let 声明的全局变量不会成为 window 对象的属性,而 var 声明的全局变量则会挂载到 window 对象上。
var name = "Matt".
console.log(window.name); //Matt
let name = "Matt"
console.log(window.name);//undefined
四:变量提升
这是 let 与 var 之间的另一个核心区别:let 声明的变量不会在作用域内进行提升。
console.log(name); //undefined
var name = "Matt";
console.log(name); //ReferenceError: name is not defined
let name = "Matt"
在代码解析阶段,JavaScript 引擎会识别后续的 let 声明(即所谓的“类似提升”行为),但在该变量实际声明之前,任何对该变量的访问操作都会导致红色的 ReferenceError 错误。这一未初始化状态下的访问区间被称为“暂时性死区”(Temporal Dead Zone, TDZ)。这在一定程度上强制提升了代码的规范性。
其他:
1. ES6 明确规定,在 {} 代码块中出现 let 或 const 声明时,变量将被限制在该块级作用域内。
2. 函数声明的提升优先级高于 var 的变量提升。为避免混淆和潜在错误,建议避免变量重名(正如部门内重名人员可能带来的管理麻烦一样)。
以上就是 ECMAScript 中 var、let、const 常见问题及区别详解的详细内容,更多关于 ECMAScript 中 var、let、const 区别的资料请关注本站其它相关文章!
JS中将数组和对象混合组装为JSON字符串
2026-11-05 16:41:42
JS运算符优先级与结合性的区别是什么?
2026-11-05 13:22:02
JS Map怎么只遍历Key或Value
2026-11-05 13:00:36
D3.js 与 ECharts 选型对比:灵活性 vs 开发效率
2026-11-05 09:45:01
为什么JS中typeof []返回object:数组类型检测误区解析
2026-11-04 19:50:47
