From 80573153b8b314178437ea8557b2fd67e5c2c098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Tue, 20 Oct 2015 21:39:49 +0200 Subject: [PATCH] util: make inherits work with classes 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: https://github.com/nodejs/node/issues/3452 PR-URL: https://github.com/nodejs/node/pull/3455 Reviewed-By: Sakthipriyan Vairamani Reviewed-By: James M Snell --- lib/util.js | 9 +------- test/parallel/test-util-inherits.js | 34 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/lib/util.js b/lib/util.js index 19d3d464f104d4..d143552615baa2 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 baa77ea4405484..a3c5786fe261d0 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);