What is Prototype Inheritance in JavaScript?
Overview
Prototype inheritance in javascript is the linking of prototypes of a parent object to a child object to share and utilize the properties of a parent class using a child class.
Prototypes are hidden objects that are used to share the properties and methods of a parent class to child classes.
Syntax
The syntax used for prototype inheritance has the __proto__ property which is used to access the prototype of the child. The syntax to perform a prototype inheritance is as follows :
Example
Let us consider two objects, company, and worker. The company object has a method called pay and property called name and the worker has a method called work and property called id.
You can run this on the browser's console (press Ctrl+Shift+J (Windows) or Ctrl+Option+J (Mac)).
Output:
The first [[Prototype]] : Object you see is the prototype of the company object and the second one is the javascript's default Object prototype which is present in any object instance.
Now we can use any method and properties from the company object using the worker object. We will revisit how the properties and methods of a object are being inherited in the later part of the article.
Cons Of Prototypical Inheritance
- It reduces flexibility as a single __proto__ property can inherit only one class.
- Multiple inheritances can only be achieved at a different level. If we want to inherit a second class we need to use the __proto__.__proto__ property which makes the hierarchy complex and difficult to keep track of.
- Only objects are available for making prototype relations.
- Accessing elements with the same name as an element in the base class is difficult, that is you can have properties in different classes with the same name, but accessing them is difficult.
- Same prototypes can't be inherited as this can form a loop.
Properties And Methods
__proto__
- The __proto__ property is a used to access and change the prototype of an object.
- It is denoted by [[prototype]].
The __proto__ is a safe way to access the [[prototype]] object and not the object itself.
Object.create
- Prototype inheritance can be easily done using the Object.create method, which is used to create a new object by using the existing object.
- The new object just inherits the prototype of the given object
Let us create a new employee called intern with property inheriting from company.
This creates an object intern having a property of experience and properties from the company's prototype.
Output:
Object.prototype.constructor
- Constructor is a method, present in every object in the Object [[prototype]].
- Every object has a default constructor and constructors can also be assigned to values
The .constructor method is used to access the constructor.
Output shows the constructor method:
hasOwnProperty
- This method is used to check whether a property is present in the given object. The syntax of this method is...
- It returns true if the property is present and false if it isn't.
Let us consider a simple example,
Output:
The prototype chain
- The prototype chain is used for multiple inheritances at different hierarchy levels.
- We can make a prototypes point to other prototypes using the following method.
Consider the example where the student prototype is linked to school first and tuition next in order.
The structure of stdent object will be,
The output will be based on hierarchy:
Setting Up Prototypical Relationships
A prototypical relationship can be created by performing prototype inheritance. The objects involved in the prototypical relationship are called child and parent.
The child is the object which inherits the properties of the parent object. Let us consider the following example in which the prototype relation is made using the __proto__ prroperty.
From the example, we can see that the inherited class or the child class can access the properties of the parent class.
Inheriting Methods
The prototype inheritance not only inherits the properties of the object, it also inherits the methods of the object. We can define a function in the parent class and call the function using the child class. We can also add a getter and setter method to the parent class which can be used by the child class.
For example:
Output:
The getter and setter method in the above code represented by the syntax,
These methods are used to set the value to the properties of the object and also print the values that are currently set to the properties of the object. Using these kinds of getter and setter we can easily modify and display the properties of the parent object.
In our example, the child object is developer and the parent object is base user.
Multi-Tier Inheritance With Scalability
-
We can achieve more scalability in prototype inheritance by including the __proto__ property directly in the class.
-
We can have more complex relations which can be altered very easily when needed. This is a powerful feature of prototype inheritance in javascript. Consider a system having three inheritances such as in the case of the university student.
The output will be IT. This way of approach makes inheritance more efficient and simple.
Objects Inherit From Objects
- On knowing about prototype inheritance, we can say that two or more objects are linked using inheritance to share their properties.
- This may satisfy the statement object inherits object, but in javascript, this is not completely true.
- Javascript is a prototype-based language and uses hidden objects called prototypes in inheritance.
- Therefore, in javascript objects don't directly inherit from objects but use a property called prototype to accomplish inheritance.
Function Prototypes
- Javascript is completely an object-oriented programming language, where functions are also objects.
- Therefore, functions also have a prototype and an empty constructor by default.
- We can add any properties to the prototype of functions by using the function. prototype property.
Consider the simple example,
Output:
We can see that the prototype has been modified and the student also has a unique value called id.
The arrow function in javascript doesn't have a default prototype.
Differential Inheritance
In prototype inheritance, when using the Object.prototype method to assign properties to a prototype, the properties are not actually copied from parent to child but they are just linked with each other. This model is called Differential Inheritance in javascript and is more often referred to as prototype chain.
We can verify this using the hasOwnProperty() method. Let us consider the example of the above section here and check for the name property.
Output:
Since student has its own property called id we get true and since only the prototype has the property called name we get false.
Standard Way To Implement Prototypal Inheritance In ES5
The ES5 introduced two differnd mthods such as Object.create() and Object.getPrototypeOf().
- The object.create has the following syntax and is used to create a new object inheriting the prototype of a given object.
- The Object.getPrototypeOf() method is used to get the type of prototype from the object.
Let us consider a simple example to understand this further.
This has the following output which only shows the prototype object:
Extending The Prototype Chain
Every object has a prototype object which can be accessed by Object.prototype property. By using this we can extend a prototype chain.
New initialization
The prototype of a function object can't be directly modified. So we use a function object to assign the prototype of a function to another function object.
The output denotes the structure of inheritance:
Object.setPrototypeOf
This method can be used to set the prototype for any object using another object's prototype.
The syntax is:
Let us perform the above example using this method.
The simplified output will be as follows:
This output has a separate prototype object for the first as it copies the prototype of the first into the second object.
Prototype And Object.getPrototypeOf
The Object.getPrototypeOf() is used to get the prototype of a object specified in the parameter.
Syntax :
For example :
The above example has an object two which is extended from object one using the method of chain linking and the getPrototypeOf() method is used to get the prototype of object two.
Conclusion
- Prototype inheritance in javascript is performed using the prototype property present in every object.
- The main advantage of performing prototype inheritance is to make methods available in a class to the other classes.
- The __proto__ property or the Object.create() method can be used to perform prototype inheritance.
- Multiple inheritance can be done by forming a prototype chain which is more scalable.
- The prototype chain follows differential inheritance model and this can be verified using the has own property() method.
- There are predefined ways to implement prototypal inheritance in ES5 using Object.create() and Object.getPrototypeOf().
- The prototype chain can be extended using new initialization and Object.setPrototypeOf().