我有一个使用原型继承的旧代码库,其中充满了一些外部类的子类。最近,该外部类已被移植到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内部的学习练习/好奇心。
答案 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.prototype
指x
类的构造方法。