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 theEmployee
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.
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 ---> nullvar 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 new Operator. How new operator works:
The new
keyword does the following things:
- Creates a blank, plain JavaScript object;
- Links (sets the constructor of) this object to another object;
- Passes the newly created object from Step 1 as the
this
context; - 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.

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 Employee
— Manager
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 functionObject.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