如何使用 ES5 原型重构 class 表达式?

How do I refactor a class expression with ES5 prototypes?

如何使用 ES5 原型语法重构 class 表达式?

我正在尝试使用 class 表达式扩展本机 class。此代码工作正常,但扩展本机 classes 是 ,我想在将来将我的代码转换为 ES5。

这是取自 google's custom elements primer 的代码。

customElements.define('bigger-img', class extends Image {
    // Give img default size if users don't specify.
    constructor(width = 50, height = 50) {
        super(width * 10, height * 10);
    }
}, { extends: 'img' });

所以问题很简单:

如何用 ES5 兼容的东西重构 ES2015 class 表达式(或者只是 babel 兼容,但这个问题与 babel 并没有真正的关系)。

您能否简要解释一下或向我指出解释 ES6 classes 如何与原型一起工作的参考资料?

Class ES5 中的扩展有点棘手。您需要使用原型链来完成此操作。为此,您需要知道原型的作用。

给定以下函数:

function BaseClass(){
}

您可以为其原型添加属性:

BaseClass.prototype.doSomething();

创建 class 的实例时,您可以在创建的对象上调用该函数:

var baseObj = new BaseClass();
baseObj.doSomething();

这个行得通,因为有一个叫__proto__的属性是由生成函数的prototype决定的(这里是:BaseClass)。

如果您访问一个不直接存在的对象上的 属性,解释器现在开始查找原型链(检查 obj.__proto__ 是否有这个 属性)。

那么如果你想扩展 BaseClass 怎么办?您需要为扩展做两件事:

  • 调用基类的构造函数class

  • 将原型加入原型链

function DerivedClass(){
    BaseClass.call(this);
}
DerivedClass.prototype.__proto__ = BaseClass.prototype; // That's what happens
DerivedClass.prototype = Object.create( BaseClass.prototype ); // That's how you should do it

生成器函数的prototype成为其生成对象的__proto__属性。

https://reinteractive.com/posts/235-es6-classes-and-javascript-prototypes

这里说的是,新语法只是一种更舒适的方式来完成我上面解释的内容。在内部它应该或多或少完全相同。

正如评论中所指出的,您永远不应手动分配 __proto__,而应使用 Object.create( prototypeObject )