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
指的是x
class.
的构造方法
由于您 运行 在实际支持真正的 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);
我会非常感谢那些批评这个代码示例的人,也许我们会得到更多的细节。提前感谢大家!!!
我有一个旧代码库,其中包含一些外部 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
指的是x
class.
由于您 运行 在实际支持真正的 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);
我会非常感谢那些批评这个代码示例的人,也许我们会得到更多的细节。提前感谢大家!!!