Hello World, prototype is a fundamental concept every developer delving into JavaScript must understand. In this post, I intend to explain the JavaScript's prototype to you in an easily digestible manner. If you are ready, let's get started.
What is Prototype
Every JavaScript object or function has a special hidden or internal property that is empty by default. This internal property can reference another object. At each time we create a function in JavaScript, JavaScript engine adds an extra property called prototype to the created function. This prototype property is an object (called as prototype object) The object the internal property points to is what we call a "prototype object". So Prototype property is simply a reference to another object. This is important as it helps have access to some methods stored in memory without recreating them from scratch. Consider the example code using the constructor
//Define the blueprint for manufacturing cars
function Car(){
this.model= "Audi";
this.year = 2021
this.seat = 5
this.drive = function(){
return "I am a cruising "
};
}
//create a new car object so we can inherit the properties of the Car
const car1 = new Car()
console.log(car1.design()); // I am a sleek vehicle
//This concept helps us extend the functionality of car1 by simply focusing on the new things to add to it
Meaning Of Prototype In English Language vrs JS
In English language, we may define a prototype as the first or preliminary version of a device from which other forms are developed.
Similarly, in the world of JavaScript, there is a prototype which is the first object or function from which other objects are developed.
In our example above, we developed car1 from Car object, making Car the prototype of car1
Why Is The Prototype Pattern Important ?
A prototype object serves as blueprint for each object the constructor creates. If the prototype of a constructor used contains a property make as in the example above, then each object created by that same constructor will also have this same property.
With this concept, anytime we read a property from an object and it is missing, JavaScript will automatically check the prototype object, see if the property is available there and take the value of the property from there. This pattern provides as an easy way to implement inheritance in JavaScript a concept that allows objects to inherit methods from the prototype.
Prototypal Inheritance
In javaScript, we can often use built-in methods such as
.length, .map() and .join()
on our strings, arrays and object. Even though we never explicitly specify them, these methods are internal properties every object have. Any object you create, can inherit or have access to these in built methods. That explains why we can use the example below to get the length of an array
const num=[2, 4, 5, 21, 10, 13]
console.log(num.length) // 6
So how do we get the length of the array to be 6 ? Lets console.log(num) and see what is under the hood. When we console.log(num) we have access to the following
(6) [2, 4, 5, 21, 10, 13]
0: 2
1: 4
2: 5
3: 21
4: 10
5: 13
length: 6
__proto__: Array(0)
The proto above is that internal or hidden property that gives as access to all the in-built array methods in JavaScript. Any object we create, can inherit this "proto " property and have access to a method that was not explicitly created by the object.
Setting The Prototype Property
As mentioned earlier, the property [[Prototype]] is internal and hidden, but we can set it using the
_proto_ //not the recommended method of setting prototype though
Let's take a look at how to set a prototype property on an object
//parent object
let vehicle = {
tyres : 4,
make: "Audi"
}
// define a new object
let sedan = {
year: "2021"
}
sedan.__proto__ = vehicle
// set vehicle to be the prototype of sedan
// Now if we read a property from sedan and it is missing,
// JavaScript will automatically look at the prototype, in this case **vehicle ** and and inherit the property from there.
//Now if can have access to the "make" property
console.log(sedan.make) // returns Audi
- Scenario 2: Let's take another look on how to set a prototype on an object
let animal = {
legs: 4,
jumps: true,
walk(){
return "Animal can walk "
}
}
let sheep ={
furs: true,
feeds: "grass"
}
//set animal to be the prototype of sheep
sheep.__proto__ = animal
//Now all the properties and methods of animal becomes available in sheep.
// Such properties are called inherited
//If we have any method in animal it can be accessed or inherited by the sheep object
//walk() is taken from the prototype
console.log(sheep.walk()) // Animal can walk
Prototype Chain
When an object gets a request for a property that it does not have, the first reaction is to check the prototype to see if we can locate the property. If we still cannot find it, we search the prototype's prototype and so on this what we refer to as prototype chain. It is basically an object looking upward to find where it inherited a property from
Let see how that works
let animal = {
legs: 4,
jumps: true,
walk(){
return "Can walk "
}
}
let feed ={
eats: "grass",
__proto__: animal // set animal to be the prototype of feed
}
let horse = {
hoof: true,
fur: true,
__proto__: feed //set feed to be the prototype of horse
}
//horse accesses the walk() method
console.log(horse.walk()) // Can walk
With the above , if we try to access the walk() method from the horse object and it is not available, we look for it in the feed object(parent protoptype), if we still can't access the method, we look finally at and in the animal object (grand parent prototype) , we eventually find out that the "walk()" method was created in the animal object. That is why the horse object can have access to the walk() method.
Recommend Way Of Setting Prototype
If you have understood the concept of prototype, then the next bit about constructors should not be confusing, let's dig further. The recommended way of setting the prototype of an object is Object.create instead of the proto used earlier.
Object.create very simply returns a new object with the specified prototype and any additional properties you want to add. For our purposes you use it like so
//Define the blueprint for manufacturing cars
function Car(name, yearMade, passengers){
this.name = name
this.year = yearMade
this.manufacturer= "VW"
this.passengers = passengers
}
//Extend the functionality of the blueprint
//set prototype of Car object to getDesign method
Car.prototype.getDesign = function(){
console.log(`I am a sleek ${this.name} vehicle`)
}
//set prototype of Car object to getPessenger method
Car.prototype.getPessenger = function(){
console.log(`The ${this.name} can take up to ${this.passengers} passengers`)
}
//create a constructor function
function Sedan(name, passengers){
this.name =name
this.passengers = passengers
}
//set the prototype of the Sedan object to a new object that has a copy of Car.prototype and all its props
Sedan.prototype = Object.create(Car.prototype);
//Any new instance of the constructor function can inherit all properties of the Car object prototype
AudiSedan = new Sedan("Audi2021", 4)
//access the getDesign method
AudiSedan.getDesign() // "I am a sleek Audi2021 vehicle"
AudiSedan.getPessenger() //"The Audi2021 can take up to 4 vehicle"
After creating the constructor for Sedan we set it’s prototype to a new object that has a copy of Car.prototype.. Now any new object created from the Sedan constructor can inherit all the methods of the Car prototype
In Conclusion
To summarize, prototype is basically a method that was set or initialized when a function was first created. When we create a function, the JavaScript engine creates a prototype object for that function and adds a prototype property to the function.
Any instance of that function will have access to all the prototype object that was set by the function.
This then helps to extend the functionality of the object as new instances can inherit all the prototype objects that has been defined.
Trust you learnt something new ? Your feedback will be greatly appreciated, Me daa se .
PS: Me daa se means "Thank You" in Twi, one of the most popular dialects in my country Ghana