diff --git a/lib/util.js b/lib/util.js index 19d3d464f1..d143552615 100644 --- a/lib/util.js +++ b/lib/util.js @@ -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) { diff --git a/test/parallel/test-util-inherits.js b/test/parallel/test-util-inherits.js index baa77ea440..a3c5786fe2 100644 --- a/test/parallel/test-util-inherits.js +++ b/test/parallel/test-util-inherits.js @@ -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);