Reading Nodejs source code - How util.inherits affects the prototypal chain?
How util.inherits works?
Node.js source code (lib -> util.js -> exports.inherits)
exports.inherits = function(ctor, superCtor) {
if (ctor === undefined || ctor === null)
throw new TypeError('The constructor to "inherits" must not be ' +
'null or undefined');
if (superCtor === undefined || superCtor === null)
throw new TypeError('The super constructor to "inherits" must not ' +
'be null or undefined');
if (superCtor.prototype === undefined)
throw new TypeError('The super constructor to "inherits" must ' +
'have a prototype');
ctor.super_ = superCtor;
Object.setPrototypeOf(ctor.prototype, superCtor.prototype);
};
Use of util.inherits in _stream_readable.js
util.inherits(Readable, Stream);
.
.
.
util.inherits is used to extend the prototypal chain using another function constructor’s prototype property
In the case of util.inherits(Readable, Stream)
‘Readable’ becomes the ‘ctor’ and ‘Stream’ becomes the ‘superCtor’.
Object.setPrototypeOf(ctor.prototype, superCtor.prototype)
sets the _proto_ property of Readable’s prototype property (which is an object) to the prototype property of Stream
, a function constructor.
To understand how util.inherits
works better I wrote the following code
Code
function Person() {
this.firstName = "John";
this.lastName = "Doe";
}
Person.prototype.getFullName = function() {
return this.firstName + " " + this.lastName;
}
var michael = new Person();
console.log(michael);
// Prototypal Chain for 'michael'
console.log("\nPrototypal Chain for 'michael'");
console.log(michael.__proto__);
console.log(michael.__proto__.__proto__);
console.log(michael.__proto__.__proto__.__proto__);
Output
Person { firstName: 'John', lastName: 'Doe' }
Prototypal Chain for 'michael'
Person { getFullName: [Function] }
{}
null
Code
var util = require('util');
function Person() {
this.firstName = "John";
this.lastName = "Doe";
}
Person.prototype.getFullName = function() {
return this.firstName + " " + this.lastName;
}
function Vehicle() {
this.car = "Honda";
this.wheels = 4;
this.getWheels = function() {
return this.wheels;
}
}
Vehicle.prototype.getCar = function() {
return this.car;
}
util.inherits(Person, Vehicle);
var michael = new Person();
console.log(michael);
// Prototypal Chain for 'michael'
console.log("\nPrototypal Chain for 'michael'");
console.log(michael.__proto__);
console.log(michael.__proto__.__proto__);
console.log(michael.__proto__.__proto__.__proto__);
Output
Person { firstName: 'John', lastName: 'Doe' }
Prototypal Chain for 'michael'
Person { getFullName: [Function] }
Vehicle { getCar: [Function] }
{}
Summary
util.inherits()
-
Gives access to methods and properties defined on the prototype of the Function constructor
-
Affects the prototypal chain
-
Only adds properties and methods that are defined on the prototype of the Function constructor
-
Does not add properties or methods defined inside the Function Constructor