ES6类的原始继承 [英] proto inheritance from ES6 class

查看:71
本文介绍了ES6类的原始继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an old codebase full of subclasses of a some external class, using prototypal inheritance. Recently, this external class has been ported to an ES6 class, but also has new features I'd like to use. Prototypal inheritance doesn't work anymore, and I'm wondering if it's possible to make it work even if it's with some ugly hack. This is basically what I'm trying to do:

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'


$ b $,则不能调用类构造函数ClassParent b

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

Please don't post answers like "you should port your subclasses to ES6". I know that's probably the appropriate thing to do, take this question more as a learning exercise / curiosity about JS internals.

推荐答案

如果您在实际上支持真正的ES6类的环境上运行所有这些,则可以实现所需的功能。您需要做的就是将子类逻辑更改为

Since you're running this all on an environment that actually supports real ES6 classes, you may be able to achieve what you're looking for. What you'll need to do is to change your subclass logic to be

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 也很重要。只要两者都可用,就非常接近复制使用实际的类语法获得的行为。就是说,问题立即就出在您为什么不做

This is predicated on Reflect.construct being available, so it will not work on an older ES5 environment, but then neither would ES6 class syntax either. It's also important that new.target be available. As long as both are available, this is very close to replicating the behavior you'd get from using actual class syntax. That said, immediately the question would be why you're not just doing

class ProtoChildFromClassParent extends ClassParent {}

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

so whether this is useful or not really depends on what's stopping you from doing that to begin with.

这篇关于ES6类的原始继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆