JavaScript OOP Using Constructor Functions

Object Oriented Programming can be implemented in JavaScript in three ways

  • Constructor Function
  • ES6 Class
  • Object.create()

In this article, I’ll go over the first way, which is using constructor functions. Using constructor functions is the oldest and main method of doing OOP in JavaScript.

Our Sample Object

Imagine our objective is to be able to programmatically create objects representing cars with specific properties and functionalities. For instance, each car can have make and speed as its properties, and also accelerate and brake as its functionalities (or methods). So if car1 is an instance of the object, it may look something like:

As you can see, make and speed are the properties of the objects, we wanna create. We also wanna be able to call accelerate() and brake() on all instances.

What Is a Constructor Function

Technically, a constructor function is just a normal function. There’s nothing special about a constructor function. It’s basically a function that receives the properties (and not methods) as parameters. So in our example, it might be something like this:

Here, Car is the constructor function. It receives the properties (make and speed) as its parameters and sets them on the this keyword. Again notice that there’s nothing special about the constructor functions. All the magic happens when we create an instance of the object using the new keyword.

Prototype

All objects in JavaScript have a prototype. The prototype is itself an object which contains all the functionalities (methods) of the first object. For instance, all arrays have a prototype which is an object that contains all the array methods like map, filter, push and pop. Similarly, all strings have a prototype object that includes all string methods like toLowerCase and slice. Also, all functions (which are also objects) have access to methods like call and bind via their prototype.

All of these were examples of standard object types which are behind the scenes created using their respective standard constructor function like Array(), String() and Function(). Similarly, when we create a custom object type (like Car) using a constructor function, we should create the prototype for the object instances that will be created from that instructor function. We do this by creating a property for the constructor function called prototype. This prototype property is an object that includes all the methods we want the object instances to have.

Note that Car.prototype is the prototype property of the constructor function. It is an object which contains all methods that object instances will have access to.

This prototype property of the constructor function will be the prototype of the object instances created with that constructor function. In other words, Car.prototype will be car1.__proto__ and car2.__proto__

You can access the prototype of any object, using its __proto__ property.

Creating an Instance Using the new Keyword

When we wanna create an instance of the object, we use the new operator like this:

The new operator is where all the magic is. When we use the new operator like this, it does four things:

  1. It creates an empty object {}
  2. It executes the constructor function and passes that empty object as this to the function
  3. It sets the prototype of the formerly empty object (which now has some properties like make and speed) equal to the prototype property of the constructor function
  4. It returns that object from the constructor function

So this is what happens in the above code:

  1. The new operator creates an empty object {}
  2. It’ll execute the Car function and set this to the empty object. so that object will be {make:”Lexus” , speed:120}
  3. It’ll set the prototype of this object equal to the prototype property of the constructor function. {make:”Lexus” , speed:120}.__proto = Car.prototype
  4. It’ll return this object from the constructor function. So at the end car1 is {make:”Lexus” , speed:120} and it also have access to all methods in its prototype.

Creating a Child Class

Imagin we wanna create a new class for electric cars. We want them to have the make and speed property but also have a charge property. We write the constructor function like this:

Here, we’re creating the constructor function just as usual. The only thing is that instead of setting the make and speed properties directly on the this keyword (which is possible) we call the parent constructor function with call method and pass this as a parameter. The only reason for doing this is that we don’t wanna repeat the code which already exists in the parent constructor function.

In this stage, we created the ElectricCar constructor function but it’s still doesn’t inherit from the Car class. In other words, the instances of ElectricCar won’t have access to the methods in the Car.prototype. To set the inheritance, we need to set the prototype of ElectricCar.prototype to be Car.prototype. We do this by using Object.create()

Note that Object.create() creates an empty object and sets that object’s prototype to the parameter we pass to it.

Now the prototype chain is set. In other words now ElectricCar.prototype.__proto__ is equal to Car.prototype

So now all instances of ElectricCar will have access to methods in Car.prototype via Prototypal inheritance

Now that the inheritance is set up properly, we can add new methods to the child class prototype or add new versions of existing methods (Polymorphism)

You can find all sample codes in this code pen.