const 声明:JavaScript 中的常量 🔒
核心理念:
const
是现代JavaScript中最推荐的变量声明方式,表示”不可重新赋值”的意图
🎯 const 的基本特性
📋 与 let 的主要区别
// ✅ const 必须在声明时初始化
const userName = 'Alice';
const userAge = 25;
const isActive = true;
// ❌ const 不能未初始化
const message; // SyntaxError: Missing initializer in const declaration
🚫 不可重新赋值
const score = 100;
score = 150; // TypeError: Assignment to constant variable.
// ❌ 不能重复声明
const product = 'iPhone';
const product = 'iPad'; // SyntaxError: Identifier 'product' has already been declared
📦 块级作用域
const globalName = 'Global';
if (true) {
const localName = 'Local';
console.log(globalName); // 'Global' - 可以访问外层
console.log(localName); // 'Local'
}
console.log(globalName); // 'Global'
console.log(localName); // ReferenceError: localName is not defined
💡 深入理解:引用不可变 vs 值可变
🔑 核心概念
const
保护的是变量的引用地址,而不是引用指向的值本身。
📊 原始类型(完全不可变)
const num = 42; // 数字不可变
const str = 'Hello'; // 字符串不可变
const bool = true; // 布尔值不可变
const n = null; // null 不可变
const u = undefined; // undefined 不可变
// 以下操作都会报错
// num = 43; // TypeError
// str = 'Hi'; // TypeError
// bool = false; // TypeError
🏗️ 引用类型(内容可变)
// ✅ 对象:引用不可变,但属性可变
const user = {
name: 'Alice',
age: 25
};
// ✅ 可以修改属性
user.name = 'Bob';
user.email = 'bob@example.com';
delete user.age;
console.log(user); // { name: 'Bob', email: 'bob@example.com' }
// ❌ 但不能重新赋值整个对象
// user = { name: 'Charlie' }; // TypeError
// ✅ 数组:引用不可变,但元素可变
const colors = ['red', 'blue'];
colors.push('green'); // ✅ 添加元素
colors[0] = 'yellow'; // ✅ 修改元素
colors.pop(); // ✅ 删除元素
console.log(colors); // ['yellow', 'blue']
// ❌ 但不能重新赋值整个数组
// colors = ['purple']; // TypeError
🛠️ 常见使用场景
📝 配置对象
// ✅ 配置对象使用 const
const API_CONFIG = {
baseURL: 'https://api.example.com',
timeout: 5000,
retryAttempts: 3
};
// 可以动态修改配置
if (process.env.NODE_ENV === 'development') {
API_CONFIG.baseURL = 'http://localhost:3000';
API_CONFIG.timeout = 10000;
}
🏭 函数声明
// ✅ 函数表达式使用 const
const calculateTotal = (items) => {
return items.reduce((sum, item) => sum + item.price, 0);
};
const formatCurrency = (amount) => {
return new Intl.NumberFormat('zh-CN', {
style: 'currency',
currency: 'CNY'
}).format(amount);
};
// ✅ 对象方法
const mathUtils = {
add: (a, b) => a + b,
multiply: (a, b) => a * b,
power: (base, exponent) => Math.pow(base, exponent)
};
📦 模块导入
// ✅ 导入的模块使用 const
const express = require('express');
const { readFile, writeFile } = require('fs').promises;
const path = require('path');
// ES6 模块
import React from 'react';
import { useState, useEffect } from 'react';
🔄 循环中的 const 使用
✅ for…in 循环
const userObj = { name: 'Alice', age: 25, city: 'Beijing' };
for (const key in userObj) {
console.log(`${key}: ${userObj[key]}`);
// key 在每次迭代中都是新的常量
}
// 输出:
// name: Alice
// age: 25
// city: Beijing
✅ for…of 循环
const fruits = ['apple', 'banana', 'orange'];
for (const fruit of fruits) {
console.log(`I like ${fruit}`);
// fruit 在每次迭代中都是新的常量
}
// 输出:
// I like apple
// I like banana
// I like orange
// 复杂示例:处理对象数组
const users = [
{ id: 1, name: 'Alice', active: true },
{ id: 2, name: 'Bob', active: false },
{ id: 3, name: 'Charlie', active: true }
];
for (const user of users) {
if (user.active) {
console.log(`Active user: ${user.name}`);
}
}
❌ 传统 for 循环中的限制
// ❌ 这样不行,因为 i 需要递增
// for (const i = 0; i < 5; i++) { ... }
// ✅ 正确的做法:循环变量用 let,其他用 const
for (let i = 0; i < 5; i++) {
const message = `Count: ${i}`;
const doubled = i * 2;
console.log(message, doubled);
}
🔧 实际应用技巧
🎨 样式和主题配置
const THEME_CONFIG = {
colors: {
primary: '#007bff',
secondary: '#6c757d',
success: '#28a745',
danger: '#dc3545'
},
fonts: {
primary: '"Helvetica Neue", Arial, sans-serif',
monospace: '"SF Mono", Monaco, monospace'
},
spacing: {
small: '8px',
medium: '16px',
large: '24px'
}
};
// 可以基于条件修改主题
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
THEME_CONFIG.colors.primary = '#0d6efd';
THEME_CONFIG.colors.background = '#212529';
}
📱 组件配置
// React 组件示例
const UserProfile = () => {
// ✅ 配置对象使用 const
const defaultProps = {
showAvatar: true,
showEmail: true,
showPhone: false,
theme: 'light'
};
// ✅ 样式对象使用 const
const styles = {
container: {
padding: '16px',
borderRadius: '8px',
backgroundColor: defaultProps.theme === 'dark' ? '#333' : '#fff'
},
avatar: {
width: '64px',
height: '64px',
borderRadius: '50%'
}
};
return (
<div style={styles.container}>
{/* 组件内容 */}
</div>
);
};
⚠️ 常见误区和最佳实践
🔍 误区1:认为 const 完全不可变
// ❌ 错误理解:认为 const 对象完全不能改变
const settings = { theme: 'light' };
// settings.theme = 'dark'; // 有些人认为这会报错,实际上是可以的
// ✅ 正确理解:const 保护引用,不保护内容
settings.theme = 'dark'; // ✅ 可以修改属性
settings.newProp = 'value'; // ✅ 可以添加属性
// settings = {}; // ❌ 不能重新赋值
🔍 误区2:过度使用 Object.freeze()
// ⚠️ 不必要的复杂化
const config = Object.freeze({
apiUrl: 'https://api.example.com'
});
// ✅ 大多数情况下,普通 const 就够了
const config = {
apiUrl: 'https://api.example.com'
};
// 团队约定不修改配置对象,比强制冻结更实用
🔍 误区3:在不合适的地方使用 const
// ❌ 需要重新赋值的变量不要用 const
let counter = 0; // ✅ 会递增,用 let
let currentUser = null; // ✅ 会变化,用 let
let isLoading = true; // ✅ 状态会改变,用 let
// ✅ 不需要重新赋值的用 const
const maxRetries = 3; // 配置常量
const calculateScore = () => {}; // 函数
const users = []; // 数组(内容可变)
📊 性能优化建议
🚀 JavaScript引擎优化
// ✅ 使用 const 帮助引擎优化
const LARGE_DATASET = generateLargeDataset();
const PROCESSING_FUNCTION = createProcessor();
// 引擎知道这些不会被重新赋值,可以进行优化
function processData(data) {
return PROCESSING_FUNCTION(data, LARGE_DATASET);
}
📈 内存使用优化
// ✅ 在函数内使用 const 减少意外修改
function processUserData(users) {
const processed = []; // 明确这是结果容器
const batchSize = 100; // 批处理大小
const validator = createValidator(); // 验证器实例
for (let i = 0; i < users.length; i += batchSize) {
const batch = users.slice(i, i + batchSize);
for (const user of batch) {
if (validator.isValid(user)) {
processed.push(transformUser(user));
}
}
}
return processed;
}
🎯 最佳实践总结
✅ 推荐用法
// 1. 配置和常量
const CONFIG = { apiUrl: '...' };
const MAX_ITEMS = 100;
// 2. 函数声明
const handleSubmit = () => {};
// 3. 模块导入
const express = require('express');
// 4. 不会重新赋值的变量
const users = [];
const result = processData();
// 5. 循环中的临时变量
for (const item of items) {
const processed = transform(item);
}
❌ 避免用法
// 1. 需要重新赋值的变量
let counter = 0; // 不是 const counter = 0
// 2. 循环计数器
for (let i = 0; i < 10; i++) {} // 不是 const i
// 3. 条件赋值
let message; // 不是 const message;
if (condition) {
message = 'Success';
} else {
message = 'Error';
}
🎉 总结
const
声明是现代JavaScript开发的基石。它不仅让代码更安全、更可读,还能帮助JavaScript引擎进行优化。
🔑 关键要点
- 优先使用:除非需要重新赋值,否则默认用
const
- 理解本质:保护的是引用,不是引用的内容
- 适当场景:配置、函数、导入、循环遍历都很适合
- 团队约定:建立团队规范,保持代码一致性
💡 记忆技巧
“能用 const 就用 const,需要改变才用 let”
掌握 const
的正确使用是写出高质量JavaScript代码的重要一步!
下一步学习:下一篇: 声明风格及最佳实践