Skip to content

Commit

Permalink
util: make inherits work with classes
Browse files Browse the repository at this point in the history
The current implementation overwrites the prototype of the target
constructor. It is not allowed with ES2015 classes because the prototype
property is read only. Use Object.setPrototypeOf instead.

Fixes: #3452
PR-URL: #3455
Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
targos authored and rvagg committed Oct 29, 2015
1 parent c9786bb commit 8057315
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 8 deletions.
9 changes: 1 addition & 8 deletions lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -761,14 +761,7 @@ exports.inherits = function(ctor, superCtor) {
'have a prototype.');

ctor.super_ = superCtor;
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
}
});
Object.setPrototypeOf(ctor.prototype, superCtor.prototype);
};

exports._extend = function(origin, add) {
Expand Down
34 changes: 34 additions & 0 deletions test/parallel/test-util-inherits.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,40 @@ const c = new C();
assert.strictEqual(c.getValue(), 'abc');
assert.strictEqual(c.constructor, C);

// inherits can be called after setting prototype properties
function D() {
C.call(this);
this._d = 'd';
}

D.prototype.d = function() { return this._d; };
inherits(D, C);

assert.strictEqual(D.super_, C);

const d = new D();
assert.strictEqual(d.c(), 'c');
assert.strictEqual(d.d(), 'd');
assert.strictEqual(d.constructor, D);

// ES6 classes can inherit from a constructor function
class E {
constructor() {
D.call(this);
this._e = 'e';
}
e() { return this._e; }
}
inherits(E, D);

assert.strictEqual(E.super_, D);

const e = new E();
assert.strictEqual(e.getValue(), 'abc');
assert.strictEqual(e.d(), 'd');
assert.strictEqual(e.e(), 'e');
assert.strictEqual(e.constructor, E);

// should throw with invalid arguments
assert.throws(function() { inherits(A, {}); }, TypeError);
assert.throws(function() { inherits(A, null); }, TypeError);
Expand Down

0 comments on commit 8057315

Please sign in to comment.