Javascript — A prototype based language

A what language? With ES6 coming with keywords like class, constructor, super, extends, etc I wanted to understand how are they implemented in the language. On reading, I came to know that JS is a prototype based language. This is intriguing as most of the languages I’ve worked with are class based language.

Javascript is not a class based language but a prototype based language.

What does this mean? To understand this, let’s first understand what are class based languages like Java, C++. A class-based language is based on two fundamental entities: “classes” and “instances”.

  • A class is an abstract data type. It describes a family of objects that have the same set of methods and properties. It also defines these properties and methods. A class defines all of the properties that characterise a certain set of objects (considering methods and fields in Java, or members in C++, to be properties). A class is abstract rather than any particular member in a set of objects it describes. For example, the Employee class could represent the set of all employees.
  • An instance, on the other hand, is the instantiation of a class; that is, one of its members. For example, Abhinav could be an instance of the Employee class, representing a particular individual as an employee. An instance has exactly the same properties of its parent class (no more, no less).

A prototype-based language, such as JavaScript, does not make this distinction: it simply has objects. A prototype-based language has the notion of a prototypical object, an object used as a template from which to get the initial properties for a new object. Any object can specify its own properties, either when you create it or at run time. In addition, any object can be associated as the prototype for another object, allowing the second object to share the first object’s properties.

The rectangular Follow button on the left is an instance of class Rectangle for java while it’s an object in prototype based language.

So how does prototype based language model this? It’s pretty simple to model this follow button via class based approach. Shape -> Rectangle and this follow button is an instance of Rectangle. We do this in prototype based language with prototypes (obviously! hence the name).

Let’s understand some basics about prototype first. The base object in Javascript is called “Object”. Try let a = new Object() in console.

a.__proto__ gives all the methods such as {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}. This is same as Object.getPrototypeOf(a);

Every object in Javascript has a Prototype as it’s a way for it to be linked to another object. Now how to link this? There are various ways to create objects in Javascript. Whenever the objects the created, they are linked to some other object by their Prototype.

  1. Object.create

The Object.create() method creates a new object, using an existing object as the prototype of the newly created object.

var a = {a: 1}; 
// a ---> Object.prototype ---> null

var b = Object.create(a);
// b ---> a ---> Object.prototype ---> null
console.log(b.a); // 1 (inherited)

var c = Object.create(b);
// c ---> b ---> a ---> Object.prototype ---> null

var d = Object.create(null);
// d ---> null
console.log(d.hasOwnProperty);
// undefined, because d doesn't inherit from Object.prototype
// Base Object always has hasOwnProperty

We just created a prototype chain. When we attempt to access a property or method of an object, JavaScript will first search on the object itself. If not found it will repeat this process on the prototype of the object and so on till it reaches the end of chain — null (top most prototype. Everything evolved from null!).

2. Another basic way is by syntax. Javascript as language does it when we use this.

Let’s have a look at some of the prototypes chains

var o = {a: 1};
// o ---> Object.prototype ---> null
var a = [];
// a ---> Array.prototype ---> Object.prototype ---> null
var f = function () {
return 2;
}
// f ---> Function.prototype ---> Object.prototype ---> null

3. By Constructor

A “constructor” in JavaScript is “just” a function that happens to be called with the Operator. How new operator works:

The new keyword does the following things:

  1. Creates a blank, plain JavaScript object;
  2. Links (sets the constructor of) this object to another object;
  3. Passes the newly created object from Step 1 as the this context;
  4. Returns this if the function doesn't return its own object.
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
var car1 = new Car('Eagle', 'Talon TSi', 1993);
Car.prototype.sound = "Brhhhhhh"
console.log(car1.make); // 'Eagle'// car1 ---> Car ---> Object.Prototype ---> nullcar1.__proto__
{
sound: "Brhhhhhh"
constructor: ƒ Car(make, model, year)
__proto__:
constructor: ƒ Object()
hasOwnProperty: ƒ hasOwnProperty()
isPrototypeOf: ƒ isPrototypeOf()
propertyIsEnumerable: ƒ propertyIsEnumerable()
toLocaleString: ƒ toLocaleString()
toString: ƒ toString()
valueOf: ƒ valueOf()
__defineGetter__: ƒ __defineGetter__()
__defineSetter__: ƒ __defineSetter__()
__lookupGetter__: ƒ __lookupGetter__()
__lookupSetter__: ƒ __lookupSetter__()
get __proto__: ƒ __proto__()
set __proto__: ƒ __proto__()
}

There is a constructor added in Prototype when called by new

4. By Class. Let’s discuss this more below and how are super, class, extend keywords implemented.

In class-based languages, you define a class in a separate class definition. In that definition you can specify special methods, called constructors, to create instances of the class. A constructor method can specify initial values for the instance’s properties and perform other processing appropriate at creation time. You use the new operator in association with the constructor method to create class instances.

JavaScript follows a similar model, but does not have a class definition separate from the constructor. Instead, you define a constructor function to create objects with a particular initial set of properties and values. Any JavaScript function can be used as a constructor. You use the new operator with a constructor function to create a new object.

Runtime vs Compile time

In class-based languages, you typically create a class at compile time and then you instantiate instances of the class either at compile time or at run time. You cannot change the number or the type of properties of a class after you define the class. In JavaScript, however, at run time you can add or remove properties of any object. If you add a property to an object that is used as the prototype for a set of objects, the objects for which it is the prototype also get the new property.

Image for post
Image for post
Class vs prototype based languages

In a class-based language, you create a hierarchy of classes through the class definitions. In a class definition, you can specify that the new class is a subclass of an already existing class. The subclass inherits all the properties of the superclass and additionally can add new properties or modify the inherited ones.

How Javascript implements inheritance?

JavaScript implements inheritance by allowing you to associate a prototypical object with any constructor function. So, you can create exactly the EmployeeManager example, but you use slightly different terminology. First you define the Employee constructor function, specifying the name properties. Next, you define the Manager constructor function, calling the Employee constructor and specifying the name and department property. Finally, you assign a new object derived from Employee.prototype as the prototype for the Manager constructor function using setPrototypeOf / create. Then, Manager, inherits the name properties from the Employee object.

Employee -> Manager

function Employee(name) {
this.name = name;
}
Employee.prototype.sayMyName = function() {return `${this.name}`}function Manager(name, department) {
Employee.call(this, name)
this.department = department;
}
Manager.prototype.manage = function() {return `${this.name} from ${this.department} does nothing`}let manager= new Manager("Bob", "Operations");manager.manage();
// "Bob from Operations does nothing"
manager.sayMyName()
// VM8143:11 Uncaught TypeError: manager.sayMyName is not a function
Object.setPrototypeOf(Manager.prototype, Employee.prototype);
manager.sayMyName() // "Bob"

In ES6, javascript brought class keyword along with super, extends, etc. This is just the syntactic sugar as doing these complex operations every time is difficult. Being familiar with classes is extremely helpful as these are heavily adopted by React and other frameworks. This is where I used them first. Let’s do the same Employee and Manager example with class.

  • Classes are functions
let a = class {};
let b = function() {};
a.__proto__ === b.__proto__ // True
// or
Object.getPrototypeOf(a) === Object.getPrototypeOf(b); // True
  • Define a class and methods
function Employee(name) {
this.name = name;
}
Employee.prototype.sayMyName = function() {return `${this.name}`}
// Both are equivalentclass Employee {
constructor(name) {
this.name = name;
}
sayMyName() {
return `${this.name}`
}
}
  • Extending a class
function Manager(name, department) {
Employee.call(this, name)
this.department = department;
}
Object.setPrototypeOf(Manager.prototype, Employee.prototype);// Both are equivalentclass Manager extends Employee {
constructor(name, department) {
// chaining constructor with super
super(name);
this.department = department;
}
}

Both classes and constructors imitate an object-oriented inheritance model to JavaScript, which is a prototype-based inheritance language. This is just made so that it’s easy for people from class based background to shift here.
Understanding prototypical inheritance is paramount to being an effective JavaScript developer.

This is all what goes under the hood. You can contact me at abhinav.rai.1996@gmail.com

Written by

Product Engineer at Go-Jek | Guitarist | Traveller | Entrepreneur

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store