在ES2015中实现简单的属性继承?

时间:2016-07-15 06:58:17

标签: javascript ecmascript-6 babeljs

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

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

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 ???

这样做

根据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中轻松完成这项工作。必须有更好的实施或解决方法吗?

2 个答案:

答案 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