简体   繁体   English

如何使用Ecmascript 6类扩展对象文字类

[英]How to extend an object literal class with Ecmascript 6 classes

I have a base class defined as an object literal , with methods defined inside constructor's scope. 我有一个定义为object literal的基class ,其方法在构造函数的作用域内定义。 Like this: 像这样:

var NodeMappingAbstract = function NodeMappingAbstract() {

    this.mapToContent = function (obj) {
        throw new Error('Not implemented');
    };

    this.getInfo = function (data) {
        throw new Error('Not implemented');
    };

    this.normalizeUri = function normalizeUri(uri) {
        return uriNormalizer.normalize(uri);
    };
};

How do I extend the NodeMappingAbstract with ES6 class syntax? 如何使用ES6 class语法扩展NodeMappingAbstract I attempted using extends and super() : 我尝试使用extendssuper()

class SomeMapping  extends  NodeMappingAbstract{
    constructor(){
        super();
    }

    mapToContent(rawElement) {
        console.warn('mapContent called');
        return rawElement;
    }
}

But when I instantiate it and call mapToContent like this: 但是当我实例化它并像这样调用mapToContent

let m = new SomeMapping();
m.mapToContent();

I get Error: Not implemented , which means the implementation of the NodeMappingAbstract is used. 我收到Error: Not implemented ,这意味着使用了NodeMappingAbstract的实现。

The problem here is that you are attaching the methods directly on an instance of NodeMappingAbstract ( this ), and not the prototype of the function. 这里的问题是您将方法直接附加到NodeMappingAbstractthis )的实例上,而不是函数的prototype上。

When JavaScript performs a lookup for an object property it first inspects the objects immediate own properties, which are what are made available when you assign something to this . 当JavaScript对某个对象属性执行查找时,它首先检查这些对象的直接自身属性,这些属性是在您向this分配某些内容时可用的。 Only if it does not find that property immediately available in this way will it turn to the prototype . 只有当它没有发现以这种方式立即可用的属性时,它才会转向prototype So, although you are extending the NodeMappingAbstract and defining methods on the prototype (via the class sugar), you are not actually overriding the properties that are assigned to this on instantiation inside NodeMappingAbstract . 因此,尽管您正在扩展NodeMappingAbstract并在prototype上定义方法(通过class NodeMappingAbstract ),但实际上并没有覆盖NodeMappingAbstract实例化时this分配的属性。

So, move the method declarations outside of the function body and onto its prototype : 因此,将方法声明移到函数体之外并移至其prototype

var NodeMappingAbstract = function NodeMappingAbstract () {};

NodeMappingAbstract.prototype.mapToContent = function (obj) {
   throw new Error('Not implemented');
};

NodeMappingAbstract.prototype.getInfo = function (data) {
    throw new Error('Not implemented');
};

NodeMappingAbstract.prototype.normalizeUri = function normalizeUri (uri) {
    return uriNormalizer.normalize(uri);
};

You should put your methods on the prototype of your ES5 class (as you always should). 您应该将方法放在ES5类的原型上(一如既往)。

If you define them in the constructor, and create them as instance properties (which shadow anything inherited from the prototype), you will have to do the same when overwriting them: 如果在构造函数中定义它们,并将它们创建为实例属性(遮盖从原型继承的任何内容),则在覆盖它们时必须执行相同的操作:

class SomeMapping  extends  NodeMappingAbstract{
    constructor(){
        super();
        this.mapToContent = function(rawElement) {
            console.warn('mapContent called');
            return rawElement;
        };
    }
}

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

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