var与let的区别
在 JavaScript 中,var 和 let 都是用于声明变量,但它们之间存在几个关键区别,这些区别影响着变量的作用域、提升行为以及重复声明:
🧠 1. 作用域
var:函数作用域- 在函数内部声明的变量,在整个函数内部都有效。
- 在函数外部声明的变量,成为全局变量。
- 不受块级作用域约束(如
if,for,while等代码块)。在块内声明的var变量会"泄漏"到包含它的函数作用域或全局作用域中。
javascriptfunction exampleVar() { if (true) { var x = 10; // 变量 x 的作用域是整个 exampleVar 函数 } console.log(x); // 输出 10 ✅,因为 x 在 if 块外依然可见 }let:块级作用域- 变量仅在声明它的代码块(
{})内有效(包括if,for,while,switch, 以及单独的{}块)。 - 解决了
var的变量泄漏问题,使变量生命周期更精确、更可预测。
javascriptfunction exampleLet() { if (true) { let y = 20; // 变量 y 的作用域仅限于这个 if 块 console.log(y); // 输出 20 ✅ } console.log(y); // ❌ ReferenceError: y is not defined (y 在 if 块外不可见) }- 变量仅在声明它的代码块(
📦 2. 变量提升
var:声明被提升,初始化不提升- 变量的声明会被提升到其作用域(函数或全局)的顶部。
- 变量的初始化(赋值)留在原地。
- 在声明之前访问变量会得到
undefined。
javascriptconsole.log(a); // 输出 undefined ✅ (声明被提升,但值未初始化) var a = 5; console.log(a); // 输出 5 ✅let:存在"暂时性死区"- 声明也会被提升到其块级作用域的顶部。
- 但在声明语句执行之前,变量处于"暂时性死区"。在 TDZ 中访问变量会导致
ReferenceError。 - 强制你在使用前声明变量,避免意外行为。
javascriptconsole.log(b); // ❌ ReferenceError: Cannot access 'b' before initialization (处于 TDZ) let b = 10; console.log(b); // 输出 10 ✅
🔁 3. 重复声明
var:允许在相同作用域内重复声明- 不会报错,后面的声明会覆盖前面的(可能导致难以追踪的错误)。
javascriptvar c = 1; var c = 2; // ✅ 允许重复声明 console.log(c); // 输出 2let:不允许在相同作用域内重复声明- 在同一个块级作用域内重复声明同一个变量名会导致
SyntaxError。 - 有助于防止命名冲突和意外覆盖。
javascriptlet d = 3; let d = 4; // ❌ SyntaxError: Identifier 'd' has already been declared- 在同一个块级作用域内重复声明同一个变量名会导致
🧩 4. 全局作用域下的行为
var:在全局作用域声明时,会成为全局对象(浏览器中是window)的属性。javascriptvar globalVar = "I'm global"; console.log(window.globalVar); // 在浏览器中输出 "I'm global" ✅let:在全局作用域声明时,不会成为全局对象(window)的属性。javascriptlet globalLet = "I'm also global, but not attached"; console.log(window.globalLet); // 在浏览器中输出 undefined ✅
📌 总结与最佳实践
| 特性 | var | let |
|---|---|---|
| 作用域 | 函数作用域 | 块级作用域 ✅ |
| 提升 | 声明提升,初始化不提升 | 提升但存在TDZ ✅ |
| 重复声明 | 允许 ✅ | 禁止 ✅ (SyntaxError) |
| 全局属性 | 成为window属性 | 不成为window属性 ✅ |
| 现代实践 | ⚠️ 遗留,避免使用 | ✅ 推荐用于可变量声明 |
- 优先使用
let(和const):let的块级作用域和禁止重复声明特性显著提高了代码的可读性、可维护性和可靠性,避免了var常见的陷阱(如变量泄漏出循环、意外覆盖)。 - 理解
var: 主要用于理解旧代码或特定历史背景,在新项目中应避免使用。 - 使用
const: 对于值不会改变的变量,应优先使用const声明常量,这能提供额外的安全保障并表明意图。
简单来说:let 解决了 var 的主要设计缺陷,是现代 JavaScript 中声明变量的标准方式。 请尽量使用 let 和 const 替代 var。