深入理解 JavaScript 中的 const 关键字
1. const 关键字简介
const是 JavaScript 中用于声明常量的关键字,于 ES6(ECMAScript 2015)中引入。它用于声明一个只读的常量,一旦声明,其值就不能被重新赋值。
2. const 的基本特性
2.1 声明时必须初始化
使用const声明变量时,必须在声明的同时进行初始化(赋值),否则会抛出语法错误。
// 正确用法 const PI = 3.14159; // 错误用法:未初始化 const MAX_SIZE; // SyntaxError: Missing initializer in const declaration2.2 不可重新赋值
const声明的常量不能被重新赋值。尝试重新赋值会导致 TypeError。
const APP_NAME = "MyApp"; APP_NAME = "NewApp"; // TypeError: Assignment to constant variable2.3 块级作用域
与let类似,const声明的常量具有块级作用域,只在声明它的代码块内有效。
{ const LOCAL_CONST = "只在块内有效"; console.log(LOCAL_CONST); // 输出:"只在块内有效" } console.log(LOCAL_CONST); // ReferenceError: LOCAL_CONST is not defined3. const 与对象/数组
3.1 常量指向的引用不可变
const保证的是变量名指向的内存地址不变,而不是该地址存储的数据不变。对于对象和数组这样的引用类型,可以修改其属性或元素。
// 对象示例 const person = { name: "Alice", age: 25 }; person.age = 26; // 允许:修改对象属性 person.city = "Beijing"; // 允许:添加新属性 console.log(person); // { name: "Alice", age: 26, city: "Beijing" } // 数组示例 const colors = ["red", "green"]; colors.push("blue"); // 允许:添加元素 colors[0] = "yellow"; // 允许:修改元素 console.log(colors); // ["yellow", "green", "blue"]3.2 如何创建真正的不可变对象
如果需要创建完全不可变的对象,可以使用Object.freeze()方法。
const config = Object.freeze({ apiUrl: "https://api.example.com", timeout: 5000 }); config.apiUrl = "https://new.api.com"; // 静默失败(严格模式下会报错) console.log(config.apiUrl); // 仍然是 "https://api.example.com"4. const 与 let、var 的对比
| 特性 | const | let | var |
|---|---|---|---|
| 作用域 | 块级作用域 | 块级作用域 | 函数作用域/全局作用域 |
| 变量提升 | 存在暂时性死区 | 存在暂时性死区 | 变量提升,初始值为 undefined |
| 重复声明 | 不允许 | 不允许 | 允许 |
| 重新赋值 | 不允许 | 允许 | 允许 |
| 声明时初始化 | 必须 | 可选 | 可选 |
5. 最佳实践与使用场景
5.1 优先使用 const
在 ES6+ 开发中,建议优先使用const,只有在明确知道变量需要重新赋值时才使用let。这有助于提高代码的可读性和可维护性。
5.2 典型使用场景
- 配置常量:API 地址、超时时间、错误码等
- 数学常量:PI、E 等
- 导入模块:ES6 模块导入默认使用 const
- 循环中的不变值:for...of 循环中的迭代变量
// 配置常量 const API_BASE_URL = "https://api.example.com"; const MAX_RETRY_COUNT = 3; // 数学常量 const PI = Math.PI; const E = Math.E; // 模块导入 import { useState, useEffect } from 'react'; // for...of 循环 const fruits = ["apple", "banana", "orange"]; for (const fruit of fruits) { console.log(fruit); }6. 常见误区与注意事项
6.1 const 不保证对象内容不变
如前所述,const只保证引用不变,不保证对象内容不变。如果需要深度不可变,可以考虑使用 Immutable.js 等库。
6.2 暂时性死区
const声明的常量也存在暂时性死区,在声明之前访问会报错。
console.log(MY_CONST); // ReferenceError: Cannot access 'MY_CONST' before initialization const MY_CONST = "value";6.3 全局对象的属性
在全局作用域中使用const声明的常量不会成为全局对象(浏览器中的 window)的属性,而var会。
const GLOBAL_CONST = "I'm const"; var globalVar = "I'm var"; console.log(window.GLOBAL_CONST); // undefined console.log(window.globalVar); // "I'm var"7. 总结
const是 JavaScript 中声明常量的标准方式,它提供了块级作用域、不可重新赋值等特性。虽然对于引用类型只能保证引用不变,但结合良好的编程习惯和必要的工具(如Object.freeze()),可以有效地提高代码的稳定性和可维护性。在现代 JavaScript 开发中,建议遵循 "默认使用 const,需要重新赋值时使用 let,避免使用 var" 的原则。