简体   繁体   English

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

[英]How do I refactor a class expression with ES5 prototypes?

How do I refactor a class expression with ES5 prototype syntax? 如何使用ES5原型语法重构类表达式?

I'm trying to extend a native class using a class expression. 我正在尝试使用类表达式扩展本机类。 This code works fine but extending native classes is not supported by babel and I'd like to transpile my code to ES5 in the future. 该代码可以正常工作,但babel不支持扩展本机类,我希望将来将代码转换为ES5。

This is code taken off of google's custom elements primer . 这是从Google的自定义元素入门中摘录的代码。

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' });

So the question is simple: 所以问题很简单:

how do I refactor an ES2015 class expression with something ES5 compatible (or just babel compatible really but this question isn't really related to babel). 如何使用与ES5兼容的东西(或实际上与babel兼容,但是这个问题与babel无关)来重构ES2015类表达式。

Can you briefly explain or point me to reference that explains how ES6 classes work with the prototypes? 您能否简要解释一下或为我提供参考,以说明ES6类如何与原型一起使用?

Class extension in ES5 is a little bit tricky. ES5中的类扩展有些棘手。 You need to use the prototype chain to accomplish this. 您需要使用原型链来完成此任务。 To do that, you need to know what a prototype does. 为此,您需要知道原型的作用。

Given the following function: 赋予以下功能:

function BaseClass(){
}

You can add properties to its prototype: 您可以为其原型添加属性:

BaseClass.prototype.doSomething();

When creating an instance of that class, you can call that function on the object created: 创建该类的实例时,可以在创建的对象上调用该函数:

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

This works, because there is a property called __proto__ which is determined by the prototype of the generation function (here: BaseClass ). 这是__proto__ ,因为有一个称为__proto__的属性,该属性由生成函数的prototype (在这里: BaseClass )确定。

If you access a property on an object, that does not exists directly, the interpreter now starts looking through the prototype chain (checking if obj.__proto__ has this property). 如果访问对象上不直接存在的属性,则解释器现在开始浏览原型链(检查obj.__proto__是否具有此属性)。

So what if you want to extend BaseClass? 那么,如果您想扩展BaseClass怎么办? You need to do two things for an extension: 您需要对扩展做两件事:

  • Call the constructor of the base class 调用基类的构造函数

  • Add the prototype to the prototype chain 将原型添加到原型链

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

The prototype of the generator function becomes the __proto__ property of its generated objects. 生成器函数的prototype成为其生成对象的__proto__属性。

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

Here it says, that the new syntax is only a more comfortable way to accomplish what I explained above. 它说的是,新语法只是完成我上面解释的内容的一种更舒适的方法。 Internally it should do more or less exactly the same. 在内部,它应该或多或少完全相同。

As pointed out in the comments, you should never assign __proto__ manually, but use Object.create( prototypeObject ) instead. 正如评论中指出的那样,您永远不要手动分配__proto__ ,而应使用Object.create( prototypeObject )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM