JavaScript Constructor Function Explained with Examples

Robin
Updated on April 3, 2022

Object-oriented programming (OOP) is a concept used in almost every programming language. With it, you can construct a blueprint of an object. In JavaScript, there are multiple ways to work with OOP.

One of them is the constructor function. If all of this does not make any sense, don't worry. This article is all about constructor functions in JavaScript.

This is the only post you need to understand what a constructor function is, how it works with object-oriented programming and how you can create custom constructor functions in JavaScript.

Topics you will learn:

  • What is a constructor function in JavaScript?
  • Types of constructor functions.
  • What is this keyword in JavaScript?
  • How to create custom constructor functions.
  • Why should you use constructor functions in JavaScript?
  • Constructor function VS class in JavaScript
  • Many more...

What is a Constructor Function in JavaScript?

The constructor function is a special type of JavaScript function that gets used with the new operator to create and return an object. Every time a constructor function gets called, it creates a new object with values of existing object properties. This is the main purpose of using it.

Here the object is the instance of the constructor function. That means when you create one or multiple objects using a constructor function, all of them will be the instances of that function.

That's how we can use prototypal inheritance to share properties or methods that will be the same for all instances. We will learn about prototypal inheritance in a separate section later in this post.

Also Read: Factory Function in JavaScript Explained with Examples

Types of Constructors in JavaScript

There are mainly 2 types of constructors in JavaScript:

  • Built-in Constructor Functions - The constructor functions that come with JavaScript like String(), Array(), Boolean(), etc.
  • User-defined Custom Constructor Functions - The constructor functions that we create to fulfill the requirements of our own applications.

Built-in JavaScript Constructors

There are 9 built-in constructor functions available in JavaScript. These are the functions that you can use without creating them. But most of the time you don't need to use them directly.

  • new String() - Creates a new primitive string. But when we create a variable like const firstname = "John", it works like this constructor function. We use a string literal ("") instead of new String() function.
  • new Number() - Creates a new primitive number. We use number literals (10) instead of this constructor function.
  • new Boolean() - Creates a new primitive boolean. We use boolean literals (true/false) instead of this constructor function.
  • new Array() - Creates a new JavaScript array. We use an array literal ([]) instead of this constructor function.
  • new Object() - Creates a new JavaScript object. We use an object literal ({}) instead of this constructor function.
  • new Function() - Creates a new function. We use a function literal () {} instead of this constructor function.
  • new RegExp() - Creates a new RegExp object. We use a pattern literal /()/ instead of this constructor function.
  • new Date() - Creates a date object. We don't have any literal for this. To create a new date object, we have to use this constructor function.
  • new Error() - Creates a new error object. To create new error objects we have to use this constructor function.

What is this Keyword in JavaScript?

In JavaScript, this keyword refers to an object. But which object this keyword will represent depends on some situations and how it is being used.

  • Inside an object this keyword will refer to that object.
  • In the global context, along this keyword will refer to the global (window) object.
  • Inside a function, this keyword will also refer to the global (window) object. But if you are using strict mode then this will be undefined.
  • In an event, this keyword will represent the element that received that event.
  • In a constructor function or class, this keyword will represent the current instance of the constructor function.

If you want to learn more about this keyword, you will find a detailed guide here.

How to Create a Constructor Function in JavaScript

The constructor function is a regular JavaScript function. Here, you can not use the arrow function because inside this function you have access to this keyword and a constructor function always gets called with the new operator.

You can not use the array function with the new operator. That's why you can not use it as a constructor function.

By convention name of a constructor function starts with a capital letter. Do you have to use the capital letter to make it work?

No, but you should follow the convention to fall in line with the rest of the developers. Another important reason to use the capital letter is that it will help you to understand which function you should call with the new operator and which you shouldn't.

When you will see a function name starts with a capital letter that means you have to call that function with new operator because it's a constructor function. If the name starts with a small letter then you know it's a regular function, so you don't need to use new operator with it.

          function Product() {
    // add your properties
}

        

Here, I have created an empty function with the name Product().

That's it.

It's a valid constructor function when you call it with the new operator. JavaScript will not throw an error just because it is empty.

How to Call a JavaScript Constructor Function

          const book = new Product()

console.log(book);
// Product {}
        

I am creating an instance book by calling Product() function but before that, I have added the word new. If we look into the variable book, we can see it contains an empty object that is an instance of Product constructor function.

That means, the Product() function is returning an empty object even though the function is not explicitly returning anything.

          function Product() {
    this.name = 'Book';
    this.price = 19;
}

        

You can also set properties inside the constructor function. Here, I am adding name and price properties. You can add as many as you need for your application.

          const book = new Product()

console.log(book);
// Product { name: 'Book', price: 19 }

console.log(book.price);
// 19
        

When you call the constructor function, it will return a new instance with all those properties inside. You can access any property just like an object and you will get the value.

What Happens When A Constructor Gets Called?

You have seen that when you call a function using the new operator, something different happens. You will get an object as the return value which is the instance of that function.

But what else happens when a constructor function gets called.

          function Product() {
    // const this = {};

    // You can add properties to the object
    // this.name = "book";

    // return this;
}

        

There are mainly 3 things that happen when you call a constructor function with the new operator. These are:

  • JavaScript creates a new empty object inside the function.
  • The new empty object gets bound with the this keyword. That newly created object becomes the current instance and this keyword refers to it.
  • Finally, the constructor function returns that object automatically at the end.

All these happen behind the scene. It is not visible but it's there. That's why you can add any property to the this keyword inside a constructor function.

Note: You can also return any object explicitly if you want. Then the constructor function will not return the automatically created object.

But it is not recommended. Because there is no point in creating a constructor function if you don't intend to use its features.

Calling a Constructor Without The new Keyword

Now you might think about what will happen if you call a constructor function without the new operator.

          const book = Product();

console.log(book);
// undefined
        

If you call a constructor function without the new operator, it will give undefined as the return value. The this keyword will refer to the global (window) object.

JavaScript constructor functions with Parameters

Creating a constructor function as empty or setting static property values is not a good idea. In that case, all the objects will be the same.

You can set property values dynamically by passing them as parameters when you call the constructor function. In this way, property values for each object will be different.

          function Product(name, price) {
    this.name = name
    this.price = price
}

const book = new Product('Book', 19)
console.log(book)
// Product { name: 'Book', price: 19 }

const pen = new Product('Pen', 2)
console.log(pen)
Product { name: 'Pen', price: 2 }

        

When you create your constructor function, you will accept parameters. Now you can set those parameters as the property values.

While calling the constructor function, you have to pass those parameters each time. Now, if you look at the book and pen instances, they contain the same properties but different values.

Add Prototypal Inheritance in JavaScript Constructor Functions

You have seen how you can set unique values for each object by passing them as parameters. But what if you need to add some properties and methods that will be the same across all objects.

You can do this using prototypal inheritance. Whatever you add to the prototype, will be shared across all instances.

          function Product(name, price) {
    this.name = name
    this.price = price
}

Product.prototype.user = 'John'

Product.prototype.description = function () {
        return `${this.name} costs ${this.price} dollars`;
}

const book = new Product('Book', 19)
console.log(book.description())
// Book costs 19 dollars
console.log(book.user)
// John

const pen = new Product('Pen', 2)
console.log(pen.description())
// Pen costs 2 dollars
console.log(pen.user)
// John

        

To add properties and methods to the prototype, you have to access the prototype object on the constructor function.

When you add properties and methods to the prototype object, those properties and methods will be shared across all instances.

Here, I am adding a user property because one user might own all the products. I am also adding a method description() that will return information about each product.

Most of the time prototypal inheritance is used to add methods. Because they are always the same for all instances.

Now, I can access the user property and description() method on both book and pen instances. The user property value will be the same for both objects. Because it was a static value.

But the description() method will return a unique string according to the instance.

Why Should You Use Prototypal Inheritance in The Constructor Function

You might think of adding methods directly inside the Product() constructor function instead of adding them to the prototype object. But it is a good practice.

          function Product(name, price) {
    this.name = name;
    this.price = price;

    this.description = function () {
        return `${this.name} costs ${this.price} dollars`;
    };
}

        

If you add methods directly in the constructor function then all the instances will get a copy of those methods. That means, all the instances will have those methods separately even though they are the same.

javascript constructor function without prototypal inheritance

In JavaScript, when we create objects they get stored in the memory. So, if every instance has a copy of all methods separately, it will take more space in the memory. It's not an efficient way of memory management.

When you add methods or properties to the prototype then they don't get added to the main instances directly.

javascript constructor function with prototypal inheritance

That's why you should use prototypal inheritance to add methods in the constructor function. In this way, memory will store methods just once and each instance will get the references of those methods.

That's how it will save memory spaces and your application will perform faster.

How to Create Scope-safe Constructor Function in JavaScript

You already know that if you call a constructor function without the new operator, it will return undefined. If you do this accidentally, it will create bugs in your application.

So, how can you solve this problem?

There are two ways to create a scope-safe constructor function in JavaScript. The first option is by checking if this is an instance of the constructor function or the second option is by checking the new.target property. This is known as the scope-safe constructor function.

Solution 1: You can add an if statement to check if this is an instance of the constructor function. When the constructor function is called with the new operator, it will be true otherwise false.

          function Product(name, price) {
    if (!(this instanceof Product)) {
        throw new Error('Product constructor must be called with the new operator');
    }

    this.name = name;
    this.price = price;
}

        

If this is not an instance of the Product() constructor function, logic inside the if statement will run. There you can throw an error if you want.

Alternatively, you can also create a new instance if you don't want to throw an error.

          function Product(name, price) {
    if (!(this instanceof Product)) {
        return new Product(name, price);
    }

    this.name = name;
    this.price = price;
}

        

After returning a new instance, if you accidentally miss the new operator, the constructor function will return a proper instance instead of undefined.


Solution 2: You can check new.target property instead of using the instanceof. If you call the constructor function with the new operator, this property will return a reference of the function. Otherwise, it will return undefined.

          function Product(name, price) {
    if (!new.target) {
        throw new Error('Product constructor must be called with the new operator');
    }

    this.name = name;
    this.price = price;
}

        

Here, you can also throw an error or return a new instance. When you use the new operator, the if block will not run otherwise it will, like the previous solution.

          function Product(name, price) {
    if (!new.target) {
        return new Product(name, price);
    }

    this.name = name;
    this.price = price;
}

        

You can use any of the solutions. Both of them work similarly.

Why Should You Use Constructor Functions?

In JavaScript, a constructor function is used for many reasons. If you want to know why you should use this then I have a few points to show you. These are:

  • To create new custom objects - Using a constructor function you can as many objects as you want with similar properties and methods. You can pass custom values to those objects to make them unique.
  • To reduce code duplication - A constructor function works like a blueprint for objects. You have to write it one time and you can use it many times. Therefore, you don't need to copy and paste the same code multiple times.
  • Organize your project - You can organize your code by separating it into different files. You can write your constructor function in a separate file and export it. Then this function can be used in any file you want by importing it.
  • Increase performance by using inheritance - The constructor functions use prototypal inheritance. With it, you can save memory usage. When your application will use less memory, it will perform better.

Also Read: Best Guide on Dynamic Import in JavaScript for Importing Modules

Differences Between Factory and Constructor Function in JavaScript

The factory function and constructor function are used to create JavaScript objects. Even though their main purpose is the same, there are some differences when creating or using them.

  • A factory function is just a normal function so when we name this function, we use the Camel case. But it's a convention to start the name of a constructor function with a capital letter.
  • A constructor function has to call with the new operator. But a factory function does not need a new operator.
  • A factory function always has to explicitly return an object. When a constructor function is called with a new operator, JavaScript automatically creates and returns an object.
  • A factory can be created without using this keyword. But in a constructor function this keyword is required to set properties for the object.
  • Constructor functions by default support prototypal inheritance. But in factory functions, you have to add prototypal inheritance using Object.create() method.

Constructor Function VS Class in JavaScript

Constructor functions and classes in JavaScript are closely related to each other. A class is also used to create an object. But it uses a different syntax than a constructor function.

Their functionalities are the same because the class in JavaScript uses a constructor function behind the scene. JavaScript introduced classes as a modern syntax with some additional features.

There are some new features have been added to the class syntax in the latest version of JavaScript. That's why developers now prefer to use classes over constructor functions.

Inside a class, you can add a specific method called constructor() that will work as a constructor function.

In the beginning, the class syntax may seem a little complex compared to a constructor function. Because a constructor function is just a normal function so it is easy and simple to work with a function.

Conclusion

When you need to create many objects that will have similar properties and methods, you can make use of a constructor function to do it without creating them manually.

In JavaScript, you have many choices to create custom objects like factory functions, constructor functions, or classes.

In this article, I have shown everything about the constructor functions in JavaScript. You also have seen the differences among constructor functions, factory functions, and classes. Now, you can choose any of them according to your requirements.

I hope it was helpful for you. Thank you so much. Happy coding :)

Related Posts