简体   繁体   English

用属性重写进行Javascript静态类继承的正确方法是什么?

[英]What is the right way of doing Javascript static class inheritance with property override?

I've found many posts on class inheritance but not about this specific problem with changing properties on static classes. 我发现了很多关于类继承的文章,但关于静态类的属性更改这一特定问题却不是。

Here is the problem: I'm trying to implement class inheritance on JavaScript on a static class that will have some general static methods and will be extended by child classes, static as well. 这里是问题:我正在尝试在静态类上的JavaScript上实现类继承,该类将具有一些常规的静态方法,并且将由子类(也包括静态类)进行扩展。 Child classes may add more static methods and will change a configuration object. 子类可能会添加更多静态方法,并将更改配置对象。 None of them will be instantiated so I assume that I can't create the body property on the constructor as it will not be called. 它们都不会被实例化,因此我假设我无法在构造函数上创建body属性,因为不会调用它。 I have the following code working but I think it might not be the right way to do this. 我有下面的代码工作,但我认为这可能不是正确的方法。

Could you suggest a better alternative? 您能提出一个更好的选择吗?

 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()); 

class es are there for creating objects inheriting a prototype in a more convenient way. class es用于以更方便的方式创建继承原型的对象。 Actually JS has prototypal inheritance (objects got prototypes) so we could just use that: 实际上,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,
  },
});

If you need the class for something else you can still set a property: 如果您需要将该类用于其他用途,则仍然可以设置属性:

 class Animal{
    static get legs(){
       return this.body.legs;
    }
    static get head(){
        return this.body.head;
    }
 }

Animal.body = { legs: null, head: 1, };

I am not sure about the problem, but you can write something like this if you are using Babel. 我不确定这个问题,但是如果您使用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()); 

If you don't want to create a new object each time body is getted, you might put each class's object into a variable and return that variable. 如果不想每次获取body都创建一个新对象,则可以将每个类的对象放入变量中并返回该变量。 Or, you might make the code cleaner with a Map that returns the object indexed at this , allowing for only one get body definition: 或者,您可以使用返回返回在this索引的对象的Map来使代码更简洁,从而只允许一个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()); 

The IIFE ensures that the bodies are semi-private (though, they'll still be mutable if the object itself gets returned). IIFE确保主体是半私有的(尽管如果对象本身返回,它们仍然是可变的)。 If you want to additionally prevent the objects from being mutated when they're returned, you can use Object.freeze . 如果您还想防止对象在返回时发生突变,则可以使用Object.freeze (That doesn't guarantee that the objects won't be mutable - they can be unfrozen if done explicitly - but it'll make it a lot more difficult for accidental mutations to happen) (这不能保证对象不会可变-如果显式完成,它们可以被冻结-但这会使意外突变的发生变得更加困难)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM