Javascript 来自ES6类的原型继承

Javascript 来自ES6类的原型继承,javascript,ecmascript-6,prototype-programming,Javascript,Ecmascript 6,Prototype Programming,我有一个旧的代码库,里面有一些外部类的子类,使用原型继承。最近,这个外部类已经被移植到一个ES6类,但也有我想使用的新特性。原型继承已经不起作用了,我想知道是否有可能让它起作用,即使它有一些丑陋的黑客。这基本上就是我要做的: class ClassParent { constructor(a) { this.a = a; } } var ProtoChildFromClassParent = function(a) { ClassParent.call(

我有一个旧的代码库,里面有一些外部类的子类,使用原型继承。最近,这个外部类已经被移植到一个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内部结构的好奇。

对于较旧的构造函数函数模式来说只是一种更友好的语法

i、 e:

同:

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

y.prototype
指的是
x
类的构造函数方法。

由于您在一个实际支持真正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 {}

因此,这是否有用实际上取决于是什么阻止了您从一开始就这么做。

我还对如何以原型方式从ES6类继承感兴趣,只是想了解JS中的更多内容以及我可以提出的建议:

类父类{
建造师(数据){
这是#setPrivateProperty(数据);
}
#privateProperty=“父私有财产”;
#setPrivateProperty=(数据)=>{
这.#privateProperty=数据;
}
parentPublicMethod=()=>{
log(“父公共方法响应:,this.#privateProperty”);
}
}
函数子级(数据、父数据){
此.\uuuu proto\uuuu=新父级(parentData)
this.childPublicProperty=数据;
}
Child.prototype=Parent.prototype;
Child.prototype.constructor=Child;
设c=新的子数据(“子数据”、“父数据”);
//输出:“父公共方法响应:父数据”
c、 parentPublicMethod();
//输出:“子公共属性值为:子数据”
log(“子公共属性值为:”,c.childPublicProperty);
//输出:“1.子实例:true 2.父实例:true”

console.log(“1.子实例:,c.子实例,”,2.父实例:,c.父实例,”不幸的是,让常规函数构造函数扩展ES6类是完全不可能的。有时你可以假装是这样,但在这里不是。@yewang-FYI,这并不比只移植类来使用ES6语法简单,所以我希望你考虑一下。我知道,尽管我的免责声明xD,我的代码库已经移植到ES6,但这种注释必须出现在答案或注释中,我知道这是正确的解决方案。话虽如此,实现Reflect hack将是一种更快的方法,可以尝试新的父类实现,看看它的新版本是否没有破坏依赖它的旧代码库中的任何东西(除了proto继承)。如果它没有打破我的旧代码库并实现新的有用特性,那么我肯定知道将我的代码库移植到ES6是值得的。
class ProtoChildFromClassParent extends ClassParent {}