ES6 的 proto 继承 class

proto inheritance from ES6 class

我有一个旧代码库,其中包含一些外部 class 的子 class,使用原型继承。最近,这个外部 class 已移植到 ES6 class,但也有我想使用的新功能。原型继承不再起作用,我想知道是否有可能让它起作用,即使它有一些丑陋的黑客攻击。这基本上就是我想要做的:

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'

请不要post回答"you should port your subclasses to ES6"。我知道这可能是合适的做法,将这个问题更多地视为学习练习/对 JS 内部结构的好奇心。

class 只是对旧构造函数模式更友好的语法。

即:

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

等同于:

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

y.prototype指的是xclass.

的构造方法

由于您 运行 在实际支持真正的 ES6 classes 的环境中进行这一切,您也许能够实现您正在寻找的东西。您需要做的是将您的 subclass 逻辑更改为

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 class 语法也不会。 new.target 可用也很重要。只要两者都可用,这就非常接近于复制您使用实际 class 语法获得的行为。就是说,问题马上就是为什么你不只是做

class ProtoChildFromClassParent extends ClassParent {}

所以这是否有用实际上取决于是什么阻止您开始这样做。

我也对如何从 ES6 以原型方式继承感兴趣 class,只是想了解更多 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);

我会非常感谢那些批评这个代码示例的人,也许我们会得到更多的细节。提前感谢大家!!!