简体   繁体   中英

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. 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? I attempted using extends and super() :

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

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

But when I instantiate it and call mapToContent like this:

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

I get Error: Not implemented , which means the implementation of the NodeMappingAbstract is used.

The problem here is that you are attaching the methods directly on an instance of NodeMappingAbstract ( this ), and not the prototype of the function.

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 . Only if it does not find that property immediately available in this way will it turn to the 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 .

So, move the method declarations outside of the function body and onto its 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).

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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