Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
class SuperConstructor {
constructor() { this.isTheSuper = true }
superMethod() { return this }
}
function Constructor() {
// This doesn't work with ES6 classes
SuperConstructor.call( this )
this.isTheSuper = false
}
Constructor.prototype.method = function() {
return this
}
inherit( Constructor, SuperConstructor )
// This will throw a `TypeError`:
// Class constructor SuperConstructor cannot be invoked without 'new'`
var ctor = new Constructor()
function Ctor(options) {
SuperCtor.call(this, options)
}
function SuperCtor(options) {
this.works = options.works
}
inherit( Ctor, SuperCtor )
class ES6Ctor extends Ctor {
constructor(options) { super(options) }
}
var instance = new ES6Ctor({ works: true })
assert.ok( instance instanceof ES6Ctor, 'instanceof ES6Ctor' )
// As it happens, all super constructors are called...
assert.ok( inherit.works === true )
// But the prototype chain is not preserved:
// These blow up. Whiskey. Tango. Foxtrot.
assert.ok( instance instanceof Ctor, 'instanceof Ctor' )
assert.ok( instance instanceof SuperCtor, 'instanceof SuperCtor' )
@dfkaye
Copy link

dfkaye commented Jan 30, 2017

Not elegant but can be done.

class SuperConstructor {
  constructor() { this.isTheSuper = true }
  superMethod() {
    console.log("I'm super, believe me");
    return this
  }
}


function Constructor() {

  // instantiate super...
  var _super_ = new SuperConstructor( );

  // ...then hand roll the inheritance of own keys (ugh)
  for (var k in _super_) {
    this[k] = _super_[k]
  }

  this.isTheSuper = false
}

Constructor.prototype = Object.create(SuperConstructor.prototype);

Constructor.prototype.method = function() {
  return this.superMethod();
};

(new Constructor).method();
// logs => "I'm super, believe me"
/* logs (with drilldown):
   Constructor
    isTheSuper: false
    __proto__: SuperConstructor
        method: ()
        __proto__: Object
            ...
*/

@dfkaye
Copy link

dfkaye commented Jan 30, 2017

See also my outdated constructor gist which does that same inherit proto / inherit keys thing ~ https://gist.github.com/dfkaye/4772910

@jhermsmeier
Copy link
Author

jhermsmeier commented Jan 30, 2017

There's still the problem of the super constructor's code not running in the right context (the this of the inheriting constructor) – which is probably fine in quite a few cases, but doesn't quite cut it for all cases ;)

I wonder if there's some "magic" hack to invoke a ES6 class constructor in another context, that would certainly solve it... but in general I'm more concerned with backwards compatibility in the future, with ES5 code inheriting from node core classes or browser natives etc. (for example; streams).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment