The Javascript Prototype in action: Creating your own classes

In my previous post, I had briefly introduced the concept of the Prototype in Javascript.
In this post, we are going to learn how to use it with a practical example. We are going to create our own class.

Before we begin, we must know a few things:

  1. ECMAScript 2015 has introduced the ‘class’ keyword into Javascript. This is done to make it easier and more relatable to those coming from C++ or Java backgrounds.
  2. Despite this, the underlying object model in Javascript is still the same one based on prototypes.
  3. Hence, we will be creating classes in the old and traditional way just so that we get a deeper understanding of using the prototype.

Creating our first class

Let us create a class for complex numbers. Create a script.js file and type in the following code:

function Complex(x,y)
{
  this.x=x;
  this.y=y;
};

We have created our first class. Let us examine this.

Here, the function Complex is our constructor function. It acts as the constructor for our class. Inside this function, we initialize our instance properties.
Our constructor function requires two parameters x and y to create instances with. These parameters are specified in the function declaration.
Inside the function, the object attributes are set using the ‘this’ keyword. The ‘this’ keyword is analogous to that in Java or C++. It refers to the current instance being created.

Create a new instance of the class and log it to the console:

let complex1=new Complex(3,4);
console.log(complex1);

We get the following output on the browser console:

We can see that the properties ‘x’ and ‘y’ have been set on our object. So now let us add some methods.

The prototype of our class.

We want our methods to be available to every instance of our class. To make this possible, we need to define our methods on the prototype of our class, i.e., on Complex.prototype.
Now whenever we create a class, its prototype is automatically defined. To verify this, execute the following code:

console.log(Complex.prototype);

We will see the prototype object in the console.

The ‘constructor’ property of this prototype is the function Complex. This indicates that it must be referenced as Complex.prototype.
Note that our prototype has no methods as we have not defined any.

Adding methods.

The first method we want is to display our complex number. Let us call this method ‘display()’. Enter the following code:

Complex.prototype.display=function()
{
  if(this.y>=0)console.log(`${this.x}+${this.y}i`);
  else console.log(`${this.x}${this.y}i`);
};

What happens here is this:

  1. We create a property ‘display’ on Complex.prototype.
  2. This property is actually a function. Inside the function, we display our complex numbers in the appropriate format.

‘display’ is a function defined on the prototype of a constructor function, i.e., Complex. Thus, we can refer to the instance that called this method using the ‘this’ keyword.

Call ‘display’ on our object.

complex1.display();

Our output is:

3+4i

Let us add another method to calculate the modulus of the complex number and return it.

Complex.prototype.modulus=function()
{
  return Math.hypot(this.x,this.y);
};

console.log(complex1.modulus());

The Math.hypot function squares its arguments, adds them all together, and returns the square root of its sum. In this case, it returns the square root of (3*3)+(4*4)=25, i.e., 5.
We will get the following output in our browser console:

5

Wrapping it up.

We have so far seen how to create our classes using constructor functions. Now we shall see how the above class fits into the Javascript Prototype Object Model.

Execute the following:

console.log(Complex.prototype);

You will get the following output in the browser:

We have the following attributes defined on our Complex.prototype:

  1. ‘display’:Our display() function.
  2. ‘modulus’:Our modulus() function.

These are the methods we have defined above.

The ‘constructor’ property of our prototype is function Complex, i.e., the constructor function Complex. This makes sense as our prototype is the prototype of Complex.

Now expand the ‘<prototype>’ property of Complex.prototype in the browser.

We see a new object whose ‘constructor’ attribute is the function Object, i.e., this expanded object is Object.prototype.
Thus, we have the following relation:

Our complex1 object inherits all properties and methods from Complex.prototype.
As the Object class is at the topmost level in the Javascript object hierarchy, Complex.prototype inherits all properties and methods from Object.prototype. Thus, methods defined on Object.prototype are also available to complex1.
To verify this, do:

console.log(complex1.toString());

We will get the following output in the browser:

[object Object]

Leave a Reply

Your email address will not be published.