Node.js – The anatomy of inherits (How inheritance works in Node.js?)

nodejs-util-inherits-how-inheritance-works

In Node.js, util.js provides several in-built methods and one of these being ‘inherits’. util.inherits can be used to achieve inheritance. We will walk through the source code of inherits method and work out an example. An important point to note: inherits method worked slightly differently in Node.js version < 5.0.0. This method was changed as of version 5.0.0. inherits method pre version 5.0.0 had a flaw and this has been addressed in later versions. We will first look the pre 5.0.0 version followed by amended version.

The Constructors…and prototypes

We will first create two Function Constructors with a property and add a method to prototype of each constructor. A Manager constructor function with a property of managerName. And, a getManagerName method attached to its prototype

function Manager(managerName) {
    this.managerName = managerName;
}

Manager.prototype.getManagerName = function () {
    return this.managerName;
}
                                

Similarly, we will create a Constructor for Team, which will inherit Manager. Hence accepts 2 parameters, i.e. managerName and teamName. We will also attach a method to its prototype which will return the team name and the manager which manages the team.

function Team(managerName, teamName) {
    this.teamName = teamName;
    Team.super_.apply(this, arguments);
}

Team.prototype.getTeamDetails = function () {
    return this.teamName + ' is managed by ' + this.managerName;
}
                                

If you observe, in Team constructor we invoke Team.super_ method. This method will be assigned the constructor we intend to inherit when call the util.inherits function. This is similar to invoking the parent constructor in pseudo classical inheritance. For example,

function Team(managerName, teamName) {
    this.teamName = teamName;
    Manager.apply(this, arguments);
}
                                

util.inherits (pre Node.js version 5.0.0)

The util.inherits method in pre 5.0.0 versions of Node.js made use of Object.create. Below is a stripped down version of this method. I have removed additional checks for undefined arguments to keep it simple.

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

The first parameter to this function will be the constructor you want to inherit to and the second parameter will be the constructor to inherit from. I have put up a sample code to demonstrate this.

Object.create sets the Manager.Protoype as a prototype object of Team.Prototype. Hence if we create a new instance of Team constructor, the instance will have access to getManagerName() and properties from Manager constructors which were made available by assigning Manager constructor to Team.super_. Latter is later invoked using apply() as we have seen above.

However, in this process any methods created on Prototype of Team Constructor gets removed. We still have the constructor of Team.Prototype pointing back to Team because we passed this reference as a second parameter of Object.create method. A workaround to this issue will be to set any properties or methods to Team.prototype after we call the inherits function.
A snapshot of obj (new instance of Team)

This issue has been fixed in util.inherits method of Node.js versions 5.0.0 and above which we will see next...

util.inherits (Node.js version 5.0.0 and above)

The util.inherits method in Node.js version 5.0.0 and later replaces the Object.create with Object.setPrototypeOf to achieve inherits.

var inherits = function (ctor, superCtor) {
    ctor.super_ = superCtor;
    Object.setPrototypeOf(ctor.prototype, superCtor.prototype);
};
                                

I have modified the example from above section to use this method instead.

As illustrated above, any method set on Team.Prototype will be available following execution of inherits. A snapshot of obj (new instance of Team).

As expected, getTeamDetails() method is available on the prototype of the object.

Keep Exploring! Good Day!

Share this Post: