javascript类可通过私有字段+只读getter、构造时object.freeze、返回副本及工厂方法模拟不可变性:禁止外部修改,所有变更返回新实例。

JavaScript 中的 class 语法本身不直接提供“不可变对象”的能力,但可以通过约定和封装手段模拟不可变性——即**禁止外部修改实例状态,所有“变更”都返回新对象**。关键不是让属性真正只读(虽然可用 Object.freeze 辅助),而是让类的设计从接口层面拒绝突变。
用私有字段 + 只读 getter 模拟不可变属性
ES2022 起支持私有字段(#field),配合 getter 可隐藏内部状态,防止外部直接赋值:
class Point {
#x;
#y;
constructor(x, y) {
this.#x = x;
this.#y = y;
}
get x() { return this.#x; }
get y() { return this.#y; }
// 返回新实例,不修改自身
withX(newX) {
return new Point(newX, this.#y);
}
withY(newY) {
return new Point(this.#x, newY);
}
add(other) {
return new Point(this.#x + other.#x, this.#y + other.#y);
}
}
const p1 = new Point(1, 2);
// p1.x = 99; // ❌ 无效:x 是 getter,无 setter,且 #x 不可访问
const p2 = p1.withX(5); // ✅ 返回新对象:Point { x: 5, y: 2 }
构造时冻结实例(谨慎使用)
可在构造函数末尾调用 Object.freeze(this),阻止新增、删除或重写自有属性。但注意:它只做浅冻结,若属性是对象或数组,其内部仍可变:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 适合纯数据类(如仅含原始值、Date、Symbol 等)
- 若含嵌套对象,需递归 freeze 或改用结构化克隆逻辑
- 冻结后无法再添加方法(如动态挂载),也不影响 getter/setter 行为
class ImmutableConfig {
constructor(config) {
Object.assign(this, config);
Object.freeze(this); // 浅冻结
}
}
const cfg = new ImmutableConfig({ host: 'api.example.com', timeout: 5000 });
// cfg.timeout = 10000; // ❌ 在严格模式下报错
// cfg.newField = 'test'; // ❌ 无效
避免暴露可变引用
即使对象自身被冻结,若返回数组或普通对象引用,调用方仍可能修改其内容。正确做法是:返回副本(如 slice()、structuredClone() 或新对象):
class TodoList {
#items;
constructor(items = []) {
this.#items = [...items]; // 存副本
}
get items() {
return [...this.#items]; // 每次返回新数组,防止外部修改
}
add(item) {
return new TodoList([...this.#items, item]);
}
}
配合工厂函数与静态方法增强语义
把创建和转换逻辑集中到类上,明确表达“不可变操作”的意图:
class Money {
#amount;
#currency;
constructor(amount, currency) {
this.#amount = amount;
this.#currency = currency;
}
static of(amount, currency) {
return new Money(amount, currency);
}
plus(other) {
if (other.#currency !== this.#currency) {
throw new Error('Currency mismatch');
}
return Money.of(this.#amount + other.#amount, this.#currency);
}
toString() {
return `${this.#amount} ${this.#currency}`;
}
}
const m1 = Money.of(100, 'USD');
const m2 = m1.plus(Money.of(50, 'USD')); // 返回新 Money 实例
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










