在 ES2015 中实现简单属性继承

Implement simple property inheritance in ES2015?

本文关键字:简单 属性继承 实现 ES2015      更新时间:2023-09-26

注意:这不是重复的。 下面链接的问题只问类变量,而不是专门问允许继承的解决方法。 我将该问题中的答案应用于潜在的继承解决方案,但没有成功。

我需要做什么:基本属性覆盖:

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
}

我们不能用ES2015做到这一点???

根据此问题,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规则说你必须先打电话给super()。 对于 ProductB,您必须在重写属性之前调用super(),这将是错误的顺序(考虑到您的initialize()逻辑使用这些属性)。


使用 getter 将属性映射到类对象?

class ProductA {
    get weight() {
        return this.constructor.weight;
    }
}
ProductA.weight = 5;
// also for height, price, and all other properties...?

我很惊讶这甚至有效:当你扩展类时,getter 以某种方式映射回基类,除非它自己的构造函数具有该属性。 这几乎就像ProductB的原型是ProductA。

这里最大的问题是允许实例级覆盖(this.weight = 6)。 您必须添加一个 setter 方法,并修改 getter 以查看this.weight或回退到this.constructor.weight。 这基本上是重新实现简单继承。 为什么?!


此页面有更好的解决方案:

class ProductA {
    constructor(options) {
        Object.assign(this, {
            weight: 5,
            height: 10,
            price: 7
        }, options);
    }
}
class ProductB extends ProductA {
    constructor(options){
        super(Object.assign({
            height: 12
        }, options));
    }
}

仍然存在必须使用"super()"的问题,这会阻止我在运行 init 逻辑之前覆盖属性。

我在ES5中能够非常轻松地做到这一点。 必须有更好的实施或解决方法吗?

对于常量属性,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,类仍然是美化的构造函数,尽管它们受到限制。

假设 ES.如果在父类中使用initialize()错误,则下一个类字段将起作用。类字段不会违反规则,只是 ES6 类的糖语法。它们在调用添加为this属性super()。如评论中所述,请勿使用 initialize() .

也许这将是

你想要的,我想,但很难弄清楚你真正想做什么

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