Prototype in Javascript

What is prototype in JavaScript?

An encapsulation of properties that an object links to. Simply put it allows you to share functions or properties with every single object of some specific type. Now every JavaScript object has a prototype. The prototype is also an object. All JavaScript objects inherit their properties and methods from their prototype.

There are two types of prototypes:

1. A function prototype is the object instance that will become the prototype for all objects created using this function as a constructor.
2. Where as an object prototype is the object instance from which the object is inherited.

Let us take an example:

function Employee(name)
{ 
  this.name = name;
}

Now the Employee.prototype is the function prototype. If I create an object of type Employee, then it has an object prototype, which is accessible as

employee.__proto__

Please note that the Employee.prototype is pointing to the same object as employee.__proto__.

var employee = new Employee(name);
Employee.prototype ===  employee.__proto__

Similarly, if I create an another employee object then also a new object is  pointing to the Employee.prototype object.

var employee1 = new Employee(name);
employee1.__proto__ === employee.__proto__  === Employee.prototype

It means that the prototype object is shared between objects of type Employee.

How the property is read by the javascript engine?

If I type employee.salary(), it will return an error that salary method does not exist. However, if I can modify the prototype object, so that the salary() function is attached with the Employee prototype then the function salary() will be available for every single object of type Employee.

Employee.prototype.salary = function () {return 0; };

Now employee.salary() will return 0. Which means that if the object does not have a property then javascript engine will check with __proto__ object.

You can check who owns the salary object with this line of code:

employee.__proto__.hasOwnProperty('salary')

It will return true because salary is assigned to Employee prototype.

How can I change prototype object?

If you assign something to the prototype variable, a new prototype object is created. However, any existing objects are still pointing to the old prototype. so far I have two variables, employee and employee1. Both of these variables are pointing to the same prototype. Which means that the employee.age and employee1.age will return the same type i.e. undefined. However, if I change the value of a prototype age of an Employee like this:

Employee.prototype = {age: 10}

Then employee.age == employee1.age are still same, pointing to the type undefined but employee.age != Employee.prototype.

When I create a new object of an Employee like this:

var employee2 = new Employee();

The employee2 is pointing to a new prototype and employee2.age will return 10.

How inheritance works?

  • Make a call to parent function by using <base function>.call(this, <parameters>).
  • Set prototype for derived class.
  • Set prototype.constructor for derived class.
'use strict'
 
 function Employee(name){
 this.name = name
 }
 
Employee.prototype.age = 5; 
Employee.prototype.calculateSalary = function() { return 1000 };

function Manager(name) {
 // if you are not going to call the base constructor then
 // you are not going to have a name.
 Employee.call(this, name) // 1 
 this.hasCar = false;
}
 
Manager.prototype = Object.create(Employee.prototype); // 2.
Manager.prototype.constructor = Manager; //3.
 
var manager = new Manager('test');

console.log(manager.calculateSalary());

 How Prototyping is done with Classes?

'use strict'
 
 class Employee {
 constructor(name) {
 this.name = name;
 } 
 
 calculateSalary() {
 return 1000;
 }
 }
 
 class Manager extends Employee { 
 
 constructor(name, hasCar) {
 super(name);
 this.hasCar = hasCar;
 } 
 }

var manager = new Manager('test', true);
 console.log(manager.calculateSalary());