JavaScript Constructor Functions


Constructor functions are an essential part of JavaScript that help you create reusable objects with the same structure and behavior. In this blog post, we will walk you through JavaScript constructor functions, showing you how to define them, instantiate objects, and explore their role in object-oriented programming.


1. What is a JavaScript Constructor Function?

A constructor function is a special type of function in JavaScript used to create and initialize objects. Constructor functions are designed to be invoked with the new keyword, which creates a new instance of the object. When you define a constructor function, you can assign properties and methods to the object that it creates.

Syntax of a Constructor Function

function Person(firstName, lastName, age) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.age = age;
  this.greet = function() {
    console.log("Hello, " + this.firstName + " " + this.lastName);
  };
}

In this example, Person is a constructor function. The this keyword is used to assign properties (firstName, lastName, age) and methods (greet) to the object.


2. How to Use a Constructor Function

To use a constructor function, you need to call it with the new keyword. This tells JavaScript to create a new object and set this within the function to refer to that new object.

Example: Using a Constructor Function

function Person(firstName, lastName, age) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.age = age;
  this.greet = function() {
    return "Hello, " + this.firstName + " " + this.lastName;
  };
}

// Creating instances of Person
const person1 = new Person("John", "Doe", 30);
const person2 = new Person("Jane", "Smith", 25);

console.log(person1.greet());  // Output: Hello, John Doe
console.log(person2.greet());  // Output: Hello, Jane Smith

Explanation:

  • We created two instances of the Person constructor function: person1 and person2.
  • Both objects now have their own firstName, lastName, age, and greet properties and methods.

3. Constructor Function vs Object Literal

You might be wondering when to use constructor functions over object literals. Object literals are great when you need to create one-off objects, while constructor functions are more useful when you want to create multiple objects that share the same structure.

Example: Object Literal vs Constructor Function

// Object Literal
const person1 = {
  firstName: "John",
  lastName: "Doe",
  age: 30,
  greet: function() {
    return "Hello, " + this.firstName + " " + this.lastName;
  }
};

console.log(person1.greet());  // Output: Hello, John Doe

// Constructor Function
function Person(firstName, lastName, age) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.age = age;
  this.greet = function() {
    return "Hello, " + this.firstName + " " + this.lastName;
  };
}

const person2 = new Person("Jane", "Smith", 25);
console.log(person2.greet());  // Output: Hello, Jane Smith

Explanation:

  • The object literal person1 is a single object, while the constructor function allows you to create multiple objects (person2).
  • Constructor functions are ideal when you need to instantiate multiple objects with the same structure.

4. this Keyword in Constructor Functions

Inside a constructor function, this refers to the newly created object. Using this, you can assign values to properties and methods that belong to that object.

Example: this Inside Constructor Functions

function Book(title, author, year) {
  this.title = title;
  this.author = author;
  this.year = year;
  this.getSummary = function() {
    return `${this.title} by ${this.author}, published in ${this.year}`;
  };
}

const book1 = new Book("1984", "George Orwell", 1949);
const book2 = new Book("To Kill a Mockingbird", "Harper Lee", 1960);

console.log(book1.getSummary());  // Output: 1984 by George Orwell, published in 1949
console.log(book2.getSummary());  // Output: To Kill a Mockingbird by Harper Lee, published in 1960

Explanation:

  • this inside the constructor function refers to the newly created object (book1 or book2).
  • The getSummary method uses this to access the properties of the object (title, author, year).

5. Constructor Function Inheritance

One of the main advantages of constructor functions is that you can use them to implement inheritance. By using the prototype chain, objects created with one constructor function can inherit properties and methods from another constructor.

Example: Inheritance with Constructor Functions

function Animal(name, species) {
  this.name = name;
  this.species = species;
}

Animal.prototype.getInfo = function() {
  return `${this.name} is a ${this.species}`;
};

function Dog(name, breed) {
  Animal.call(this, name, "dog");
  this.breed = breed;
}

// Inherit from Animal
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

const dog1 = new Dog("Buddy", "Golden Retriever");
console.log(dog1.getInfo());  // Output: Buddy is a dog

Explanation:

  • The Dog constructor function inherits from Animal. This is done using call() and setting Dog.prototype to be an instance of Animal.prototype.
  • Now, all instances of Dog inherit the getInfo method from the Animal prototype.

6. Prototypes and Constructor Functions

In JavaScript, every constructor function has a prototype property. The prototype object is shared by all instances of the constructor. You can add methods and properties to the prototype to ensure that all instances of the object share the same methods, improving memory usage and performance.

Example: Adding Methods to the Prototype

function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}

Car.prototype.getCarInfo = function() {
  return `${this.year} ${this.make} ${this.model}`;
};

const car1 = new Car("Toyota", "Corolla", 2021);
const car2 = new Car("Honda", "Civic", 2020);

console.log(car1.getCarInfo());  // Output: 2021 Toyota Corolla
console.log(car2.getCarInfo());  // Output: 2020 Honda Civic

Explanation:

  • The getCarInfo method is added to Car.prototype, so all instances of Car share the same method, saving memory.