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引擎进行优化。

🔑 关键要点

  1. 优先使用:除非需要重新赋值,否则默认用 const
  2. 理解本质:保护的是引用,不是引用的内容
  3. 适当场景:配置、函数、导入、循环遍历都很适合
  4. 团队约定:建立团队规范,保持代码一致性

💡 记忆技巧

“能用 const 就用 const,需要改变才用 let”

掌握 const 的正确使用是写出高质量JavaScript代码的重要一步!


下一步学习下一篇: 声明风格及最佳实践