justinfagnani / mixwith.js

A mixin library for ES6

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Decorator for super-call?

StevenLangbroek opened this issue · comments

Calling super.method after your invocation could maybe be abstracted out into an ES2016 decorator?

let MyMixin = (superclass) => class extends superClass {
  @callSuper('before')
  foo(){
    console.log('foo from mixin');
  }
}

const callSuper = (position = 'after') => (target, name, descriptor) => {
  const originalMethod = descriptor.value;
  descriptor.value = () => {
    if (position === 'before' && super[name]) super[name].call(this, arguments);
    originalMethod.call(this, arguments);
    if (position === 'after' && super[name]) super[name].call(this, arguments);
  };
  return descriptor
};

Code is probably wrong, but just to illustrate. Thoughts?

Thanks for the suggestion @StevenLangbroek

My tests for something like this are:

  1. Is it actually much better than the default language semantics?
    1. If so, is it worth the cost in cognitive load on users and implementation complexity?

First, I'm not so sure that this:

@callSuper('before')
  foo(){
    console.log('foo from mixin');
  }

Is better than this:

  foo(){
    super.foo();
    console.log('foo from mixin');
  }

What problem does it solve? You can forget the decorator add easily as the support call. It's also using nonstandard features.

Even if it were better, simulating the semantics of super would require code that has a cost.

One thing I might be interested in is a mixin transformer that causes every method in as mixin to delegate. Using it would look like this:

const M = DelegatingMixin('before', s => class extends s {});

Would that help?

I'm going to close this as super.method() is very standard and offers the most flexibility.