应将全局常量集中定义为Object.freeze冻结的对象,并用const声明防止重新赋值;注意其仅浅冻结,嵌套对象需递归冻结;浏览器中可配合Object.defineProperty锁定全局属性。

全局常量一旦被意外修改,可能引发难以排查的 bug。用 Object.freeze 保护全局对象是常见做法,但它**不能直接冻结原始值(如字符串、数字)或全局变量本身**,只能冻结对象的属性。所以关键在于:把常量组织成一个不可变的对象,并确保它在全局作用域中只读。
把常量集中定义为一个冻结对象
不要逐个声明全局常量(如 const API_URL = '...'),而是统一放在一个对象里,再用 Object.freeze 锁定:
// ✅ 推荐:集中管理 + 冻结
const CONSTANTS = Object.freeze({
API_BASE: 'https://www.php.cn/link/710ba53b0d353329706ee1bedf4b9b39',
MAX_RETRY: 3,
TIMEOUT_MS: 5000,
ENV: 'production'
});
<p>// 尝试修改会静默失败(非严格模式)或报错(严格模式)
CONSTANTS.API_BASE = '<a href="https://www.php.cn/link/04fa8fa0d1eb99fd42854b748aa297a8">https://www.php.cn/link/04fa8fa0d1eb99fd42854b748aa297a8</a>'; // 无效
console.log(CONSTANTS.API_BASE); // 仍是 '<a href="https://www.php.cn/link/710ba53b0d353329706ee1bedf4b9b39">https://www.php.cn/link/710ba53b0d353329706ee1bedf4b9b39</a>'
防止对象被重新赋值(配合 const 声明)
Object.freeze 只冻结对象的属性,不阻止变量被重新赋值。必须搭配 const 声明,否则仍可覆盖整个引用:
-
const CONSTANTS = Object.freeze({...})→ 安全:不能改引用,也不能改属性 -
let CONSTANTS = Object.freeze({...})→ 不安全:虽然属性冻住了,但CONSTANTS = {}仍可执行
深层冻结需递归处理(可选进阶)
Object.freeze 是浅冻结——如果常量对象里嵌套了其他对象,那些嵌套对象的属性仍可修改:
在调试 Java 后端 API 故障时使用此技能,尤其适用于以下任务:分析日志、跨 Controller、Service 和 Mapper 层追踪请求、定位异常根因、检查 SQL 执行或参数流转,以及生成简洁的诊断结论与修复方案。
立即学习“Java免费学习笔记(深入)”;
const CONFIG = Object.freeze({
server: { host: 'localhost', port: 3000 },
features: ['auth', 'logging']
});
<p>CONFIG.server.port = 8080; // ❌ 仍能改!因为 server 对象没被冻结
如需完全不可变,得手动递归冻结(或使用第三方库如 deep-freeze):
- 对每个嵌套对象也调用
Object.freeze - 或写一个简单递归函数:
function deepFreeze(obj) { Object.keys(obj).forEach(key => obj[key] && typeof obj[key] === 'object' && deepFreeze(obj[key])); return Object.freeze(obj); }
浏览器环境补充:防篡改全局对象
在浏览器中,全局对象是 window(或 globalThis)。若想让 CONSTANTS 真正“挂载”到全局且防删改,可结合 Object.defineProperty:
Object.defineProperty(globalThis, 'CONSTANTS', {
value: Object.freeze({ /* ... */ }),
writable: false,
enumerable: true,
configurable: false // 防止 delete window.CONSTANTS
});
这样既冻结内容,又锁定属性描述符,进一步加固。

















