javascript中无真正只读变量,但可通过const声明、object.freeze()、getter访问器、模块封装及typescript readonly等分层手段模拟只读行为,各层作用范围与限制需明确区分。

JavaScript 中没有真正意义上的“只读变量”,但可以通过多种方式模拟只读行为,防止意外修改。关键在于理解不同场景下的实现逻辑和保护边界——变量声明方式、对象属性控制、以及运行时防护策略。
用 const 声明基础值的不可重新赋值
const 并非让值“不可变”,而是禁止对绑定的重新赋值。适用于原始类型(字符串、数字、布尔等)和引用类型(对象、数组)的引用地址锁定。
- 原始类型:一旦赋值,无法再改 ——
const PI = 3.14; PI = 3.14159;会报错 - 引用类型:只能保证变量不指向新对象,但对象内部仍可修改 ——
const arr = [1]; arr.push(2);合法,arr = [];才报错 - 建议:优先用
const替代let/var,减少意外重赋值风险
冻结对象属性:Object.freeze()
对对象本身做深度“浅冻结”:禁止添加、删除、修改已有属性(包括属性值),但对嵌套对象无效。
const config = Object.freeze({ host: 'api.example.com', port: 80 });-
config.host = 'newhost';在严格模式下静默失败或抛错(取决于环境) - 注意:
Object.freeze({ user: { name: 'Alice' } })不冻结user.name,需递归冻结或配合Object.seal()/Object.preventExtensions()组合使用
用 getter 定义只读访问器
在类或对象中通过 get 语法暴露计算值或封装私有数据,避免直接暴露可写属性。
- 类中示例:
class Timer { constructor() { this._start = Date.now(); } get elapsed() { return Date.now() - this._start; } } - 普通对象也可用
Object.defineProperty设置只读get,不设set即不可写 - 优势:支持动态计算、隐藏内部状态、便于后期加逻辑(如日志、校验)
模块级常量与防御性封装
结合 ES 模块机制 + 封装,从设计上限制访问路径。
- 导出常量对象时统一冻结:
export const SETTINGS = Object.freeze({ timeout: 5000, retry: 3 }); - 用闭包封装私有状态,仅暴露只读方法:
const createCounter = () => { let count = 0; return { get value() { return count; }, increment() { count++; } }; }; - 工具辅助:TypeScript 的
readonly修饰符可在编译期提示错误,但运行时无约束,需配合 JS 运行时策略
不复杂但容易忽略:只读是分层的——声明层(const)、对象层(freeze)、访问层(getter)、模块层(封装)。实际项目中应按需组合,而非依赖单一手段。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











