Skip to content

internals.Server does not allow proto inheritance #2663

@harrytruong

Description

@harrytruong

https://github.com/hapijs/hapi/blob/master/lib/server.js#L27

exports = module.exports = internals.Server = function (options) {

    Hoek.assert(this.constructor === internals.Server, 'Server must be instantiated using new');

Is there a reason why this.constructor === internals.Server is used? This breaks prototypical inheritance, preventing the internals.Server class from being extended.

Here's a simplified setup for the issue:

var Server = function(options) {
  if (this.constructor !== Server) throw 'Must use new.'; 
}

// this inheritance helper comes from babel (6to5)
function inherits(subClass, superClass) {
    subClass.prototype = Object.create(
        superClass.prototype,
        { constructor: {
            value: subClass,
            enumerable: false,
            writable: true,
            configurable: true
        } }
    );

    Object.setPrototypeOf(subClass, superClass);
}

// extended child of Server (inheritance style comes from babel/6to5)
var BlueServer = (function (_Server) {
    inherits(BlueServer, _Server);
    function BlueServer(options) {
        Object.getPrototypeOf(BlueServer.prototype).constructor.call(this, options);
    }
    return BlueServer;
})(Server);

The following works properly:

var server = new Server(); // no error, good.
var server = Server(); // throws "use new" error, good.

But this throws an error, when it shouldn't:

var blueServer = new BlueServer(); // throws "use new" error, BAD

Changing (this.constructor !== Server) to !(this instanceof Server) fixes the issue:

var server = new Server(); // no error, good.
var server = Server(); // throws "use new" error, good.

var blueServer = new BlueServer(); // no error, good.
var blueServer = BlueServer(); // throws "use new" error, good.

blueServer instanceof Server; // true, respects prototypical inheritance

This issue is directly related to outmoded/hapi-contrib#43. I wasn't sure if I needed to file the issue in both places.

Metadata

Metadata

Assignees

Labels

featureNew functionality or improvement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions