In this article, we shall discuss prototype in Javascript and how it works under the hood. Often developers who are new to Javascript wonder what is this magic keyword and how the heck it gives access to some methods you never define? Let us find out what prototype is all about.
Introduction to Javascript prototype
By default, Javascript provides the Object() function. You can verify it by printing it in the console.
console.log(Object);
output:
Object() though seems like an object, it's a function and not an object. It might be a little confusing but remember that Object() is a function and it provides an anonymous object that can be referenced using prototype keyword.
console.log(Object.prototype);
output:
This Object.prototype object has predefined methods such as toString() , valueOf(). In JS, when a function is a value of a property of an object, it's called a method.
The constructor of Object.prototype, in turn, references the Object function:
Let's understand it better using an example. let's define a constructor function called Programmer.
function Programmer(name, language) {
this.name = name;
this.language = language;
}
The above constructor function accepts name and language as parameters and assigns them to the name and language properties respectively. Behind the scene, JS creates a new function Programmer() and an anonymous object.
so similar to what we saw earlier in the case of object function, even this Programmer() function has a property called prototype that references an anonymous object and constructor of which references back to the Programmer() function.
Let us print both in the console and see the output:
console.log(Programmer);
Output:
console.log(Programmer.prototype);
Output:
We can observe that the object we get from Programmer.prototype has a constructor that is referencing the Programmer() function itself. In addition to this, JS links the Programmer.prototype to Object.prototype object via [[ prototype ]], this is known as prototype linkage.
The Image will help you understand it better:
Defining custom methods in the Javascript prototype
You can define your own custom methods in the prototype object. These custom functions are further accessible to the instances created from that function.
The following code defines a new method called intro() on Programmer.prototype:
Programmer.prototype.intro = function() {
return "Hello, My name is " + this.name + " and I am a " + this.language + " Developer";
}
This intro() function is added to the Programmer.prototype object.
Now, let's create an instance of the Programmer
let p = new Programmer('Jay', 'Python');
The JS will now create a new object p and links to Programmer.prototype object via the prototype linkage.
Now let's call the intro() function from this p instance:
let introduction = p.intro();
console.log(introduction);
Output:
How does this work?
Since p doesn't have its own intro() method, Javascript follows the prototype linkage and finds it on the Programmer.prototype object and executes it.
Now let's try to call toString( ) method on p object.
let pString = p.toString();
console.log(pString);
How does this work?
Again, since p doesn't have its own toString( ) method, Javascript follows the prototype linkage and searches for it on the Programmer.prototype object. Because the Programmer.prototype doesn't have the toString( ) ,method, it further follows the prototype linkage and searches in the Object.prototype object. It finds toString( ) here and executes it:
If you call a method that doesn't exist up the prototype linkage, i.e. on the Programmer.prototype or Object.prototype, then Javascript will throw an error that it cannot find the method specified.
p.changeProfession();
since changeProfession( ); doesn't exist on any of the objects in the prototype chain javascript throws an error.
let's create another instance called q:
const q = new Programmer('Raj', 'Javascript');
Now, p and q both the objects have the same objects and properties. But what if we define another method on q ? will p be able to access it ?
The code defines method getSalary( ) on q object.
q.getSalary = function () {
return "My salary is decent.";
}
This getSalary( ) method is added to only q object and not on Programmer.prototype or p.
If you try to call getSalary( ) function with p: it will throw an error:
The Dunder Proto (_ _ proto _ _)
The proto is pronounced as dunder proto. The proto is an accessor property of the Object.prototype object. It exposes the internal prototype linkage ( [[Prototype]]) of an object through which it is accessed.
The p.proto exposes the [[Prototype]] that references the Programmer.prototype object.
console.log(p.__proto__ === Programmer.prototype); // true
console.log(p.__proto__ === q.__proto__); // true
You should, however, use the Object.getPrototypeOf() method instead of the proto. The Object.getPrototypeOf() method returns the prototype of a specified object.
console.log(p.__proto__ === Object.getPrototypeOf(p)); // true
Another popular way to get the prototype linkage when the Object.getPrototypeOf() method wasn’t available is via the constructor property as follows:
p.constructor.prototype
The p.constructor
returns programmer, therefore, p.constructor.prototype
returns the prototype object.
Shadowing
See the following method call:
console.log(p.intro());
The p object doesn’t have the intro() method defined, therefore JavaScript goes up to the prototype chain to find it. In this case, it can find the method in the Programmer.prototype object.
Let’s add a new method to the object p with the same name as the method in the Programmer.prototype object:
p.intro = function() {
console.log('Hello');
}
And call the intro( ) method:
console.log(p.intro());
Because the p object has the intro() method, JavaScript just executes it immediately without looking it up in the prototype chain.
This is an example of shadowing. The intro() method of the p object shadows the intro() method of the prototype object which the p object references.
Top comments (0)