如果我希望我的类不可变,我知道我可以使用Object.freeze()
。现在,如果我希望我的对象在构造后不可变,我会放Object.freeze(this)
作为最后一行进入我的构造函数。但现在,如果我想子类化它,我无法添加更多参数,因为我无法调用this
打电话之前super
打电话后super
它是不可变的:
class A {
constructor(x) {
this.x = x
Object.freeze(this)
}
}
class B extends A {
constructor(x, y) {
this.y = y // nope. No "this" before "super"
super(x)
this.y = y // nope. "this" is already frozen
Object.freeze(this)
}
}
我正在考虑弄清楚是否通过 super 调用构造函数以跳过冻结并将冻结留给子类,但这会将其留给子类来冻结或不冻结。我该如何最好地处理这个问题?也许有工厂?
首先,你想要混合类(其基本原则基本上是状态可变性和不变性)似乎很奇怪。我认为,具有组合的可组合工厂函数可能更惯用(可能有比以下更好的方法):
function compose(funcs...) {
return function(...args) {
const obj = funcs.reduce((obj, func) = >{
return func(obj, args);
}, {});
}
return Object.freeze(obj);
}
function a(obj, { x }) {
obj.x = x;
return obj;
}
function b(obj, { y }) {
obj.y = y;
return obj;
}
const ab = compose(a, b);
ab({ x: 1, y: 2 });
或者,如果您想坚持使用类语法,您可以使用新目标检查构造函数是否调用A is a super是否打电话:
class A {
constructor(x) {
this.x = x;
// Not a super call, thus freeze the object
if (new.target === A) {
Object.freeze(this);
}
}
}
class B extends A {
constructor(x, y) {
super(x)
this.y = y
if (new.target === B) {
Object.freeze(this)
}
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)