学习笔记

52 阅读2分钟

JavaScript变量声明:let与var的核心差异

ES6(ECMAScript 2015)作为JavaScript的现代标准,引入了letconst关键字,彻底改变了变量声明方式。


▍ 作用域:块级 vs 函数级

var的函数作用域特性

if (true) {
  var varVar = "我在块内声明";
}
console.log(varVar); // 正常输出 → 变量泄漏到全局

let的块级作用域特性

if (true) {
  let letVar = "我被锁在块内";
}
console.log(letVar); // ReferenceError → 变量被严格隔离

关键点let将变量限制在{}代码块内,彻底解决循环变量泄漏问题:

// var导致的问题
for (var i = 0; i < 5; i++) {
  setTimeout(() => console.log(i)); // 输出5个5
}

// let的解决方案
for (let j = 0; j < 5; j++) {
  setTimeout(() => console.log(j)); // 正确输出0-4
}

▍ 变量提升的陷阱

var的变量提升现象

console.log(hoistedVar); // undefined(不会报错)
var hoistedVar = "被提升的变量";

let的暂时性死区(TDZ)

console.log(deadZoneVar); // ReferenceError
let deadZoneVar = "禁止提前访问";

机制说明let声明的变量在声明前处于"暂时性死区",任何访问尝试都会直接报错。


▍ 重复声明的红线

var允许重复声明

var user = "Alice";
var user = "Bob"; // 无报错 → 潜在风险点

let禁止重复声明

let userId = 1001;
let userId = 1002; // SyntaxError → 强制变量命名规范

▍ 常量声明:const的特殊性

const PI = 3.1415; // 约定使用大写命名
PI = 3.14; // TypeError → 基本类型不可变

const config = { port: 8080 };
config.port = 3000; // 允许修改对象属性
config = {}; // TypeError → 禁止重新赋值

注意const保证的是变量指向的内存地址不变,与C++等语言的常量机制不同。


作用域类型总结表

作用域类型支持的关键字典型场景
全局作用域var(不推荐)全局配置
函数作用域var函数内部变量
块级作用域let/const(推荐)循环/条件语句

最佳实践建议

  1. 默认使用const声明变量
  2. 需要重新赋值时改用let
  3. 完全避免使用var
  4. 使用ESLint等工具强制规范

通过拥抱letconst,我们可以有效避免变量污染、意外覆盖等问题,让JavaScript代码更符合现代工程化标准。