1

I would like to create a ES6 class with inheritance from 2 classes (from external libraries), but ES6 doesn't allow that. I can't use mixins either. Imbrication seems to be my only option.

For the example, let's say i would like to have a UI component class that directly emits events, log stuff, etc. (for polymorphic purposes).

I would like to avoid the following pattern:

class UIComponent extends React.Component {
    constructor(props) {
        super(props);
        this.ee = new EventEmitter();
    }

    /*
     *   methods of my UIComponent
     */
    emitThis( val ) {
        this.emit('thisEvent', val);
    },

    onThat( func ) {
        this.on('thatEvent', func);
    },

    doThis() {
        this.specificLog("i'm doing this");
        // do stuff
    }

    /*
     *   Here i just implement all methods of EventEmitter...
     */
    on(...args) {
        this.ee.on(...args);
    }

    once(...args) {
        this.ee.once(...args);
    }

    emit(...args) {
        this.ee.emit(...args);
    }

    /* this goes on and on... */
}

Does Javascript (ES5, ES6, ES2015) allow some nicer pattern for this purpose ?

Sebastien
  • 682
  • 1
  • 14
  • 26
  • 1
    Making a React component emit seems to fight against a normal React architecture, but ignoring that, you can definitely mix on an implementation of event emitter as long as you're using one that's written with that in mind. – loganfsmyth Jul 12 '16 at 17:20
  • It is going against a normal React architecture. I would like to avoid this kind of pattern (in which i need to rewrite all eventEmitter methods - in fact i need to use a more complicated class that itself inherits from eventEmitter...) – Sebastien Jul 12 '16 at 17:23
  • See [Multiple inheritance/prototypes in JavaScript](http://stackoverflow.com/q/9163341/1529630). You can use proxys. – Oriol Jul 12 '16 at 17:48

1 Answers1

1

The pattern in ES6 is basically a mix-in that deep-copies parent prototype to child prototype, something like that

class FosterParent { ...}

class Child extends Parent { ...}

let proto = FosterParent.prototype;

do {
  for (const key of Object.keys(proto))
    if (!(key in Child.prototype))
      Child.prototype[key] = proto[key];
} while (proto = Object.getPrototypeOf(proto))

The code above is oversimplified because it copies enumerable keys and not descriptors.

In ES.Next or TypeScript decorators come to rescue. @mixin decorator from core-decorators package is supposed to do the same thing as described but with neat syntax:

class FosterParent { ...}

@mixin(FosterParent)
class Child extends Parent { ...}
Estus Flask
  • 206,104
  • 70
  • 425
  • 565