In today's blog post I will be discussing the prototypal inheritance in JavaScript.
JavaScript does not have concept of classes. The object themselves carry their data and capabilities. The lineage of the object doesn't matter, only what they can do. JavaScript is a prototypal language i.e. objects inherit from one another.
Let's understand this one by one with examples. The first thing that we need to understand is that functions in JavaScript are objects. So if we have a function named person, we can add any property to it, e.g. type.
Next, I want the person to be of different types. So I add a type property and return that object.
Please note that this time the function name is capitalized. It's just a convention followed by JavaScript developers that this function needs to be used with new keyword to create instance of Person (I will be writing blog post on constructor invocation next week). So I added this property called type which we pass when we create the object. So we passed 'employee' and 'manager' as the type in the constructor. Invoking new Person('employee') returns the "this" object with type property set to the parameter value.
Next, I want to add smile method to the Person. So you might think by adding it to Person should suffice like this:
As you can see by adding it to Person object, we don't automatically add it to the instances of the Person object. The smile method is available on Person but not on employee. The reason being when we call new Person('employee'), we return the "this" object which has only one property called type defined. Since Person.prototype does not have smile method and employee.__proto__ is created from Person.prototype we will find that there is no smile method in employee.__proto__ as well.
The way Javascript works is, when we look for a property or a method on an object, it's looked up in the following order:
1. employee object has smile method()
2. Employee.prototype has smile method() defined explicitly
3. Person prototype has smile method. Since employee prototype is created using Person prototype object (inheritance).
So, one simple way of adding the smile method to returned objects can be this:
Another way of accomplishing the same thing (which we are more interested in) can be by adding it to the Person's prototype like this:
Now employee and manager have smile method. This time, the smile method was defined in Person prototype which sets the employee and manager's prototype. Voila, this way we were able to inherit using prototype.
Now, let's just use the type property inside the smile method to show which type of employee is calling the smile method:
Next, to further improve, if we want to have separate function for Employee, we can do like this:
Here, we created Employee function which returns a Person object and passes "employee" as type. Here, we set the Employee prototype explicitly to create an object using Person prototype. As a result, we inherit everything from Person's prototype. This is what happened internally in the previous examples we saw where smile() was inherited from Person's prototype.
So in this article we saw how to implement inheritance in JavaScript and understood the underlying concept.
Image Ref: here
For future updates to my weekly blog, please subscribe to my blog via the "Subscribe To Weekly Post" feature at the right and follow me on Twitter. Until then Happy Coding :)
Follow @abhijain369
Prototypal Inheritance in JavaScript
In most languages (like Java, C#, etc) inheritance is class based. We derive one class from another to reuse the pre-written code and establish hierarchy of different types so we can use them easily throughout our application.![]() |
JavaScript does not have concept of classes. The object themselves carry their data and capabilities. The lineage of the object doesn't matter, only what they can do. JavaScript is a prototypal language i.e. objects inherit from one another.
Let's understand this one by one with examples. The first thing that we need to understand is that functions in JavaScript are objects. So if we have a function named person, we can add any property to it, e.g. type.
function person(){} person.type = 'employee'; console.log(person.type); //employee
Next, I want the person to be of different types. So I add a type property and return that object.
function Person(type){ this.type = type; } var employee = new Person('employee'); var manager = new Person('manager'); console.log(employee.type); //employee console.log(manager.type); //manager
Please note that this time the function name is capitalized. It's just a convention followed by JavaScript developers that this function needs to be used with new keyword to create instance of Person (I will be writing blog post on constructor invocation next week). So I added this property called type which we pass when we create the object. So we passed 'employee' and 'manager' as the type in the constructor. Invoking new Person('employee') returns the "this" object with type property set to the parameter value.
Next, I want to add smile method to the Person. So you might think by adding it to Person should suffice like this:
function Person(type){ this.type = type; } Person.smile = function(){ console.log("Smile"); } var employee = new Person('employee'); console.log(employee.smile()); //employee.smile is not a function console.log(employee.__proto__); //contains no smile method console.log(Person.smile()); //Smile
As you can see by adding it to Person object, we don't automatically add it to the instances of the Person object. The smile method is available on Person but not on employee. The reason being when we call new Person('employee'), we return the "this" object which has only one property called type defined. Since Person.prototype does not have smile method and employee.__proto__ is created from Person.prototype we will find that there is no smile method in employee.__proto__ as well.
The way Javascript works is, when we look for a property or a method on an object, it's looked up in the following order:
1. employee object has smile method()
2. Employee.prototype has smile method() defined explicitly
3. Person prototype has smile method. Since employee prototype is created using Person prototype object (inheritance).
So, one simple way of adding the smile method to returned objects can be this:
function Person(type){ this.type = type; this.smile = function(){ console.log("Smile"); } } var employee = new Person('employee'); var manager = new Person('manager'); console.log(employee.smile()); //Smile console.log(manager.smile()); //Smile
Another way of accomplishing the same thing (which we are more interested in) can be by adding it to the Person's prototype like this:
function Person(type){ this.type = type; } var employee = new Person('employee'); var manager = new Person('manager'); Person.prototype.smile = function(){ console.log("Smile"); } console.log(employee.smile()); //Smile console.log(employee.__proto__); //contains smile method console.log(manager.smile()); //Smile
Now employee and manager have smile method. This time, the smile method was defined in Person prototype which sets the employee and manager's prototype. Voila, this way we were able to inherit using prototype.
Now, let's just use the type property inside the smile method to show which type of employee is calling the smile method:
function Person(type){ this.type = type; } var employee = new Person('employee'); var manager = new Person('manager'); Person.prototype.smile = function(){ console.log("This is "+ this.type + " smile"); } console.log(employee.smile()); //This is employee smile console.log(manager.smile()); //This is manager smile
Next, to further improve, if we want to have separate function for Employee, we can do like this:
function Person(type){ this.type = type; } Person.prototype.smile = function(){ console.log("This is "+ this.type + " smile"); } function Employee(){ //calling constructor and passing "employee" as type Person.call(this, 'employee'); } Employee.prototype = Object.create(Person.prototype); var employee = new Employee(); console.log(employee.smile()); //Smile
Here, we created Employee function which returns a Person object and passes "employee" as type. Here, we set the Employee prototype explicitly to create an object using Person prototype. As a result, we inherit everything from Person's prototype. This is what happened internally in the previous examples we saw where smile() was inherited from Person's prototype.
Conclusion
The prototypal inheritance is a powerful concept and it's very different from other common languages like C# and Java. That is why its very important to understand this properly.So in this article we saw how to implement inheritance in JavaScript and understood the underlying concept.
Image Ref: here
For future updates to my weekly blog, please subscribe to my blog via the "Subscribe To Weekly Post" feature at the right and follow me on Twitter. Until then Happy Coding :)
Follow @abhijain369
No comments:
Post a Comment