如何实现支持链式调用、实例不可变的JS Calc类?
问题原因
- 现有代码的
add、sub方法直接修改了当前实例存储的数值,且返回原实例this,不符合「每次操作返回全新实例、不改动原有实例状态」的不可变性要求,这是不可变性相关测试失败的核心原因。
修复后代码
推荐版本(支持私有属性,强化不可变性)
class Calc { // 私有属性,避免外部意外修改实例内部值 #num constructor (num = 0) { this.#num = num; } add (a) { // 不修改当前实例,直接返回计算后的新Calc实例 return new Calc(this.#num + a); } sub (a) { return new Calc(this.#num - a); } result () { return this.#num; } }
兼容旧运行环境版本
如果环境不支持JS私有字段,可使用普通属性实现,核心逻辑一致:
class Calc { constructor (num = 0) { this.num = num; } add (a) { return new Calc(this.num + a); } sub (a) { return new Calc(this.num - a); } result () { return this.num; } }
效果验证
修复后的代码完全符合所有要求,参考用例运行结果和预期完全一致:
const calc = new Calc(); calc.result(); // 0 calc.add(5).result(); // 0 + 5 = 5 calc.add(3).sub(10).result(); // 0 + 3 - 10 = -7 const ten = calc.add(10); ten.sub(5).result(); // 10 - 5 = 5 ten.result(); // 10 原有实例状态没有被修改
- 所有操作都不会改动原有实例的状态,满足不可变性要求
- 每次操作返回的都是Calc类的新实例,支持链式调用,符合fluent interface规范
内容的提问来源于stack exchange,提问作者Ars
相关产品推荐
相关产品推荐

