This is the second article in a series about prototypal inheritance in JavaScript. Have a look at the first article about Inheritance in JavaScript.
The prototype chain is the way inheritance in JavaScript is achieved. There are three common ways to create a prototype chain:
- functional
- constructor functions (this article)
- class-syntax constructors
This article will cover the constructor functions approach on creating prototype chains.
Prototypal Inheritance (Constructor Functions)
The creation of an object with a specific prototype object can be achieved by calling a function with the new
keyword. This is a very common pattern in older code bases.
All functions have a prototype property. To create a prototype with a constructor function, the properties have to be defined on the function's object and then the function has to be called with the new
keyword.
For the example code, we will use the animal
and dog
taxonomy, where animal is a prototype of dog.
function Animal(name) {
this.name = name;
}
Animal.prototype.eat = function() {
console.log(this.name + ' eats');
};
function Dog(name) {
Animal.call(this, name);
}
// this is a helper function and it could look different in older code bases
function inherit(proto) {
function ChainLink() {}
ChainLink.prototype = proto;
return new ChainLink();
}
Dog.prototype = inherit(Animal.prototype);
Dog.prototype.bark = function() {
console.log(this.name + ' barks');
};
const henry = new Dog('Henry');
henry.bark();
henry.eat();
The code above results in the exact prototype chain as in the functional approach.
console.log(Object.getPrototypeOf(henry) === Dog.prototype); //Will be true
console.log(
Object.getPrototypeOf(Dog.prototype) === Animal.prototype,
); //Will be true
It's a convention to write the functions called with new
(Animal and Dog) in PascalCase.
The eat
method was added to Animal.prototype without ever instantiating an object and assigning it to Animal.prototype. The reason for this is that every function has a pre-existing prototype object. The Dog.prototype
was explicitly assigned and overwrites the previous Dog.prototype object.
The prototype chain looks like this:
- the prototype of henry is Dog.prototype
- the prototype of Dog.prototype is Animal.prototype
- the prototype of Animal.prototype is Object.prototype.
With ECMAScript 5+ instead of the inherit
function, the Object.create
method could be used.
function Dog(name) {
Animal.call(this, name);
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.bark = function() {
console.log(this.name + 'barks');
};
In Node.js there is a utility function for this util.inherits
.
const util = require('util');
function Dog(name) {
Animal.call(this, name);
}
Dog.prototype.bark = function() {
console.log(this.name + ' barks');
};
util.inherits(Dog.prototype, Animal.prototype);
TL;DR
- Inheritance in JavaScript is achieved with a chain of prototypes
- There are three common ways to create a prototype chain (functional, constructor functions, class-syntax constructors)
- The constructor approach is to define properties on a function's prototype object and then call it with
new
. -
util.inherits
is a utility function in Node.js to set and overwrite prototypes of objects.
Thanks for reading and if you have any questions , use the comment function or send me a message @mariokandut.
If you want to know more about Javascript , have a look at these Javascript Tutorials.
Top comments (0)