注意:这不是重复的。下面链接的问题仅仅是关于类变量,而不是特别关于允许继承的变通方法。我将该问题的答案应用于潜在的继承解决方案,但没有成功。
class ProductA {
weight: 5,
height: 10,
price: 7
}
class ProductB extends ProductA {
height: 12
}
class ProductC extends ProductA {
price: 12,
weight: 2
}
class ProductC2 extends ProductC {
height: 5
}
根据this question,ES2015不支持属性。那些答案建议:
使用构造函数?
class ProductA {
constructor(){
this.weight = 5;
this.height = 10;
this.price = 7;
}
}
// and then...?
class ProductB extends ProductA {
constructor(){
super()
this.height = 12;
}
}
这似乎可行,直到你想在ProductA的构造函数中添加this.initialize()
调用,例如......有一个ES2015规则,说你必须调用{{1在其他任何事情之前。对于ProductB,您必须在覆盖属性之前调用super()
,这将是错误的顺序(考虑到您的super()
逻辑使用这些属性)。
使用getter将属性映射到Class对象?
initialize()
我甚至对此感到惊讶:当你扩展类时,getter以某种方式映射回基类,除非它自己的构造函数具有该属性。它几乎就像ProductB的原型是ProductA。
这里的一个大问题是允许实例级覆盖(class ProductA {
get weight() {
return this.constructor.weight;
}
}
ProductA.weight = 5;
// also for height, price, and all other properties...?
)。您必须添加setter方法,并修改getter以查看this.weight = 6
或回退到this.weight
。这基本上是重新实现简单的继承。为什么呢?!
This page有更好的解决方案:
this.constructor.weight
仍然存在必须使用" super()"的问题,这会阻止我在运行init逻辑之前覆盖属性。
我能够在ES5中轻松完成这项工作。必须有更好的实施或解决方法吗?
答案 0 :(得分:1)
对于常量属性,prototype
可用于所有类。父类构造函数中的this
赋值将覆盖子项中的prototype
赋值。
class ProductA { ... }
Object.assign(ProductA.prototype, {
weight: 5,
height: 10,
price: 7
});
class ProductB extends ProductA {
constructor(){
super();
...
}
})
Object.assign(ProductB.prototype, {
height: 12
});
这适用于ES5,这适用于ES6。尽管存在限制,它仍然是JS,类仍然是美化的构造函数。
如果在父类中使用initialize()
,ES.Next类字段将起作用的假设是错误的。类字段不会破坏规则,只是ES6类的糖语法。它们被添加为this
属性after super()
call。正如评论中所述,请勿使用initialize()
。
答案 1 :(得分:0)
也许这会是你想要的,我想,但很难弄清楚你真正想做的事情
class foo {
constructor(){
this.a = 1;
this.b = 2;
this.c = 3;
if(this.construct){
this.construct();
}
this.init()
}
get myState(){
return this.a + ":" + this.b + ":" + this.c
}
init(){
log(this.myState)
}
}
class bar extends foo{
construct(){
this.a = 10;
}
}
class boo extends foo{
construct(){
this.b = 20;
}
}
var a1 = new foo(); // 1 : 2 : 3
var a2 = new bar(); // 10 : 2 : 3
var a3 = new boo(); // 1 : 20 : 3