A prototype is an object, which JavaScript assigns to every object it creates. JavaScript uses it to implement inheritance. Objects inherit the properties & methods of their Prototype. In this tutorial, we will learn what is Prototype?. How & when does JavaScript add Prototypes to an Object ?. How the Prototype chains are created etc.
Table of Contents
What is a Prototype
A Prototype is an object, which JavaScript assigns to the [[Prototype]] property of an object when it creates it.
Take a look at the person object, which we created using the object literal syntax.
1 2 3 4 5 6 7 | let person = { name:"Aida Bugg" } console.log(person); |
It has an additional Property __proto__
. The __proto__
points to the Prototype object of the person
object.
Prototype is a JavaScript Object
Prototype objects are just like any other Javascript object. If you expand the __proto__
node in the debugger console, you will that it points to an object.
In fact in the above example, the person.__proto__
points to the Object.prototype
. You can verify it by running the equality checker.
1 2 3 4 5 | console.log(Object.prototype===person.__proto__); //true |
The Object.prototype
also have a __proto__
property. But it points to null
1 2 3 4 5 | console.log(Object.prototype.__proto__); //null |
Hence the prototype relation between them is as follows
1 2 3 | person => Object.prototype => NULL |
Prototype chain
An Object has a prototype. A prototype is also an object. Hence Even it may have its own prototype object. This is referred to as prototype chain
The following example creates a person object from the Person
constructor function. In such a case the <functionName>.prototype
i.e. Person.prototype
becomes the Prototype of the newly created person
object.
1 2 3 4 5 6 7 8 9 | var Person= function() { this.name="Aida Bugg" } var person = new Person(); console.log(person); |
The following image shows the Prototype chain.
You can verify the prototype chain.
1 2 3 4 5 6 7 8 9 10 | console.log(person.__proto__=== Person.prototype); //true console.log(Person.prototype.__proto__=== Object.prototype); //true console.log(Object.prototype.__proto__); //null |
The prototype chain looks something like this.
1 2 3 | person => Person.prototype => Object.prototype => null |
You can change the Prototype
In the following example, we create a employee
& manager
object from the Person
function. Later we change the prototype of the employee
to the manager
object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | var Person= function(name) { this.name=name } var employee = new Person("John") var manager = new Person("Bill") Object.setPrototypeOf(employee,manager) //OR //employee.__proto__ = manager; console.log(employee); |
The following image shows the prototype chain
1 2 3 4 5 6 7 | console.log(employee.__proto__===manager);//true console.log(manager.__proto__ ===Person.prototype); //true console.log(Person.prototype.__proto__==Object.prototype); //true |
The prototype chain
1 2 3 | employee => manager => Person.prototype => Object.prototype |
One Prototype per object
An object can have only one Prototype. But it can become a Prototype of many other objects.
Constructor Property
If you notice in the above examples, all the prototype objects have a constructor property. The only exception is the manager prototype, which is the prototype we created manually.
The constructor property points to the constructor function that is responsible for the creation of the prototype object. We will see it in the next section.
Objects without Prototype
You can create an object without a Prototypes using the Object.create
method and passing null as its argument
1 2 3 4 5 6 | var person=Object.create(null) person.name="John"; console.log(person); |
All the other ways of creating objects will always result in objects getting a prototype object
Some Basics Terms
Here are some of the basic terms
[[Prototype]]
[[Prototype]] is the internal property of an object. It is hidden and we cannot access it directly. [[Prototype]] property can either point to null or to another object. The object that [[Prototype]] points become the prototype of the Object.
There are two ways you can access the Prototype of an object. One using the __proto__
and the other using the getPrototypeOf
method of the Object
__proto__ Property
The __proto__
is property accessor method (getter & setter). It returns the prototype of the object. Internally it accesses the [[Prototype]] property and returns the object that it points to.
__proto__
is Deprecated. Hence it is no longer recommended
1 2 3 4 5 6 7 8 9 | let person = { name:"Aida Bugg" } //Returns the prototype object of the person of the object console.log(person.__proto__); |
Object.getPrototypeOf
The second and correct way to access the [[Prototype]] is by using the function Object.getPrototypeOf
.
1 2 3 4 5 6 | let person = { name:"Aida Bugg" } console.log(Object.getPrototypeOf(person)); |
Constructor Functions
Functions are special objects in Javascript. Like all objects, they too have a prototype object. But they have not one but two Prototype objects. And that has been usually the source of confusion.
One is the Prototype of the function (__proto__
property) and the other one is the Prototype Property of the function (prototype
property).
The following code creates a Person constructor function with the name property.
1 2 3 4 5 6 7 8 9 10 11 12 | var Person= function() { this.name="Aida Bugg" } console.log(Person) *** Output *** Æ’ () { this.name="Aida Bugg" } |
The console.log(Person)
does not show anything except the function definition.
But let us check Person.__proto__
& Person.prototype
.
Prototype of a function
Functions are nothing but special objects. Like all objects even they have prototypes. You can access it from __proto__
property.
The __proto__
property points to the [[Prototype]] of the function. You can access it using the Object.getPrototypeOf(Person)
But in this example, it is not Object.prototype
1 2 3 4 5 | console.log(Object.getPrototypeOf(Person) == Object.prototype); //false |
but it is Function.prototype
1 2 3 4 5 | console.log(Object.getPrototypeOf(Person)==Function.prototype); //true |
Incidentally Function.prototype
also has a prototype. And it is Object.prototype
1 2 3 4 5 | console.log(Object.getPrototypeOf(Function.prototype) == Object.prototype); //true |
Hence our Prototype chain will look like this.
1 2 3 | Person =>Function.prototype => Object.prototype |
Prototype Property of the function
The function also has a prototype property. We usually refer to it as <functionName>.prototype
. In this example it is Person.prototype
. It also points to an object.
Now let us see the contents of the Person.prototype
.
1 2 3 | console.log(Person.prototype) |
The Prototype the Person.prototype
is Object.prototype
. You can refer to it from the
1 2 3 4 5 | console.log(Object.getPrototypeOf(Person.prototype)==Object.prototype) //true |
The constructor property points to the constructor function that responsible for the creation of the prototype object.
It is the Person function that creates the Person.prototype
. Hence the Constructor property of Person.prototype
is Person function itself.
You can see the circular relationship between the Person
function & Person.prototype
object.
Finally, the Prototype of the function & the Prototype property of the function both together is as shown below.
Create object using Constructor function
The prototype property of the function has a special purpose.
Whenever we create a new object from the function, the prototype property becomes the prototype of the newly created object. The prototype property is empty initially. but you can add properties and methods or even other objects.
Consider the following example of the Person constructor function. it will automatically come with the Person.prototype
property.
Every object, that we create with the Person function will have the Person.prototype
as their prototype. For Example both employee
& customer
object will get Person.prototype
as their prototype.
1 2 3 4 5 6 7 8 | var Person= function(name) { this.name=name } var employee = new Person("Aida Bugg"); var customer = new Person("Roger Mayer"); |
You can verify it by comparing their prototypes.
1 2 3 4 5 | console.log(employee.__proto__=== Person.prototype); console.log(customer.__proto__=== Person.prototype); |
Constructor Property
The prototype objects have a constructor property.
The constructor property points to the constructor function that is responsible for the creation of the prototype object.
Object.prototype
JavaScript has a Object()
constructor function. We can create new objects using that function.
1 2 3 4 | let person = new Object() person.name = "Aida Bugg" |
As mentioned earlier, all functions have a prototype property. So is Object()
function. It is Object.prototype
The Object.prototype
is the default Prototype object. When we create an object and did not explicitly specify the prototype, then the Object.prototype
is used as Prototype
Object.prototype
also has a constructor property. Naturally, it points to the Object()
function, because that is the function that created it.
1 2 3 4 | console.log((Object.prototype).constructor==Object) //true |
Since the constructor property returns the Object function, we can use it to create a new object
1 2 3 4 | var o2 = new (Object.prototype).constructor() console.log(o2) |
The Object.prototype
itself also has a prototype. But it is null
1 2 3 4 5 6 7 | console.log(Object.prototype.__proto__) //null or console.log(Object.getPrototypeOf(Object.prototype)) //null |
Built-in or Native Objects
There are many other built-in constructor functions in Javascript. The following tables list some of them.
String Object
The String()
constructor function creates a new String Object. The String()
function has a String.prototype
property.
1 2 3 4 | let str = new String("Hi") console.log(str) |
Hence the newly created objects will get String.prototype
as their prototype
1 2 3 4 5 | console.log(Object.getPrototypeOf(str)==String.prototype) //true |
The Prototype of String.prototype
is Object.prototype
1 2 3 4 5 | console.log(String.prototype.__proto__===Object.prototype) //true |
Hence we get the following Prototype chain
Arrays
Inheritance & Prototype
In this tutorial, we concentrated on what is Prototype & how JavaScript creates them. The Prototypes exist in JavaScript with the sole purpose of providing the inheritance feature. The next tutorial Prototype Inheritance looks into that.
Hello