ES6类的原始继承

时间:2018-07-14 23:23:37

标签: javascript ecmascript-6 prototype-programming

我有一个使用原型继承的旧代码库,其中充满了一些外部类的子类。最近,该外部类已被移植到ES6类,但还具有我想使用的新功能。原型继承不再起作用,我想知道是否有可能使它起作用,即使它带有一些丑陋的技巧也是如此。基本上,这就是我想要做的:

class ClassParent {
    constructor(a) {
        this.a = a;
    }
}

var ProtoChildFromClassParent = function(a) {
    ClassParent.call(this, a);
}
ProtoChildFromClassParent.prototype = Object.create(ClassParent.prototype);
ProtoChildFromClassParent.prototype.constructor = ProtoChildFromClassParent;

var child = new ProtoChildFromClassParent(4);
console.log(child.a);

我收到以下错误:

ClassParent.call(this, a);
                ^

TypeError: Class constructor ClassParent cannot be invoked without 'new'

请不要发布诸如“您应该将子类移植到ES6”之类的答案。我知道这可能是适当的事情,更多地将此问题作为对JS内部的学习练习/好奇心。

3 个答案:

答案 0 :(得分:4)

由于您都在实际上支持真正的ES6类的环境上运行了所有这些,因此您可能能够实现所需的功能。您需要做的就是将您的子类逻辑更改为

var ProtoChildFromClassParent = function(a) {
    const _this = Reflect.construct(ClassParent, [a], new.target);
    return _this;
}
Object.setPrototypeOf(ProtoChildFromClassParent, ClassParent);
Object.setPrototypeOf(ProtoChildFromClassParent.prototype, ClassParent.prototype);

这是基于Reflect.construct的可用,因此它不适用于较旧的ES5环境,但是ES6类语法也不会。 new.target可用也很重要。只要两者都可用,这非常接近复制您使用实际类语法获得的行为。话虽这么说,但问题立即在于您为什么不只是做

class ProtoChildFromClassParent extends ClassParent {}

所以这是否有用真的取决于您是从什么开始阻止您这样做的。

答案 1 :(得分:0)

我还对如何以原型方式从ES6类继承感兴趣,只是想了解JS方面的更多知识,以及在这里我可以提出的建议:

class Parent {
    constructor(data){
        this.#setPrivateProperty(data);
    }
    #privateProperty = "Parent private property";
    #setPrivateProperty = (data)=>{
        this.#privateProperty = data;
    }
    parentPublicMethod = ()=>{
        console.log("Parent public method responded:", this.#privateProperty);
    }
}

function Child(data, parentData){
    this.__proto__ = new Parent(parentData)
    this.childPublicProperty = data;
}

Child.prototype = Parent.prototype;
Child.prototype.constructor = Child;

let c = new Child("Child data", "Parent data");
 // Output: "Parent public method responded: Parent data"
c.parentPublicMethod();
// Output: "Child public property value is: Child data"
console.log("Child public property value is:", c.childPublicProperty); 
// Output: "1. Instance of Child: true 2. Instance of Parent: true"
console.log("1. Instance of Child:", c instanceof Child, "2. Instance of Parent:", c instanceof Parent);

我将非常感谢那些批评此代码示例的人,也许我们会得到更多详细信息。预先感谢所有人!

答案 2 :(得分:-2)

class只是较旧的构造函数功能模式的友好语法。

即:

const x = function () {};
const y = new x();

与:

class x {
  constructor () {}
}
const y = new x();

y.prototypex类的构造方法。