我发现了很多关于类继承的文章,但关于改变静态类的属性这一特定问题却不是。
这是问题所在:我正在尝试在JavaScript上的静态类上实现类继承,该类将具有一些常规的静态方法,并且将由子类(也包括静态类)进行扩展。子类可能会添加更多静态方法,并将更改配置对象。它们都不会被实例化,因此我假设我无法在构造函数上创建body
属性,因为它将不会被调用。我可以使用以下代码,但我认为这可能不是正确的方法。
您能提出一个更好的选择吗?
class Animal{
static get body(){
return {
legs: null,
head: 1,
}
}
static getLegs(){
return this.body.legs;
}
static getHead(){
return this.body.head;
}
}
class Ant extends Animal{
static get body(){
return {
legs: 6,
head: 1,
}
}
}
class Monster extends Animal{
static get body(){
return {
legs: 4,
head: 2,
}
}
}
console.log(Animal.getLegs(), Animal.getHead());
console.log(Ant.getLegs(), Ant.getHead());
console.log(Monster.getLegs(), Monster.getHead());
答案 0 :(得分:2)
class
可以用来创建对象,从而以更方便的方式继承原型。实际上,JS具有原型继承性(对象具有原型),因此我们可以使用它:
const animal = {
body: { // you can fall back to a getter at any time
legs: null,
head: 1,
},
get legs(){
return this.body.legs;
},
get head(){
return this.body.head;
}
};
const ant = Object.assign(Object.create(animal), {
body: {
legs: 6,
head: 1,
},
});
如果您需要该类的其他内容,您仍然可以设置属性:
class Animal{
static get legs(){
return this.body.legs;
}
static get head(){
return this.body.head;
}
}
Animal.body = { legs: null, head: 1, };
答案 1 :(得分:1)
我不确定这个问题,但是如果您使用Babel,则可以编写如下内容。
class Animal {
static body = {
legs: null,
head: 1,
};
static getLegs() {
return this.body.legs;
}
static getHead() {
return this.body.head;
}
}
class Ant extends Animal {
static body = {
legs: 6,
head: 1
};
}
class Monster extends Animal {
static body = {
legs: 4,
head: 2,
}
}
console.log(Animal.getLegs(), Animal.getHead());
console.log(Ant.getLegs(), Ant.getHead());
console.log(Monster.getLegs(), Monster.getHead());
答案 2 :(得分:0)
如果不想每次获取body
时都创建一个新对象,则可以将每个类的对象放入变量中并返回该变量。或者,您可以使用Map
使代码更整洁,该代码返回索引为this
的对象,仅允许一个get body
定义:
const { Animal, Ant, Monster } = (() => {
class Animal {
static get body() {
return bodies.get(this)
}
static getLegs() {
return this.body.legs;
}
static getHead() {
return this.body.head;
}
}
class Ant extends Animal {}
class Monster extends Animal {}
const bodies = new Map([
[Animal, {
legs: null,
head: 1
}],
[Ant, {
legs: 6,
head: 1
}],
[Monster, {
legs: 4,
head: 2
}]
]);
return { Animal, Ant, Monster };
})();
console.log(Animal.getLegs(), Animal.getHead());
console.log(Ant.getLegs(), Ant.getHead());
console.log(Monster.getLegs(), Monster.getHead());
IIFE确保主体是半私有的(尽管如果返回对象本身,它们仍然是可变的)。如果您还想防止对象在返回时发生突变,则可以使用Object.freeze
。 (这并不能保证对象不会发生变化-如果显式完成,则可以取消冻结这些对象-但这会使意外突变的发生更加困难)