*
Previous Error Handling in Javascript (try catch) Classes-ES6-Javascript Next

Constructor Functions in JavaScript

Constructor Functions in JavaScript

Definition: A constructor function in JavaScript is used to create and initialize objects. It acts as a blueprint for creating multiple objects with the same structure but different values.

🔧 Syntax

function Person(firstName, lastName, age, eyeColor) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.age = age;
  this.eyeColor = eyeColor;
}

To create an object using the constructor function, use the new keyword:

const person1 = new Person("John", "Doe", 30, "blue");
const person2 = new Person("Jane", "Smith", 25, "green");

💡 Example

// Constructor function
function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
  this.displayInfo = function() {
    console.log(`${this.make} ${this.model} (${this.year})`);
  };
}

// Creating objects
const car1 = new Car("Toyota", "Camry", 2020);
const car2 = new Car("Honda", "Civic", 2022);

// Using method
car1.displayInfo(); // Toyota Camry (2020)
car2.displayInfo(); // Honda Civic (2022)

Constructor Functions in JavaScript

A constructor function is a special type of function used as a blueprint to create and initialize multiple objects with shared properties and methods. It was the standard approach for object-oriented programming (OOP) in JavaScript before the introduction of ES6 classes.

How constructor functions work

When a function is called with the new keyword, it acts as a constructor. This process follows several steps:

  • A new, empty object is created and assigned to the this keyword.
  • The constructor function's body is executed, and it adds properties and methods to the this object.
  • The newly created this object is implicitly returned.

Example

// A convention is to capitalize the name of a constructor function.
function Car(make, model, year) {
  // `this` refers to the new object being created.
  this.make = make;
  this.model = model;
  this.year = year;
}

// Create new car objects (instances) using the `new` keyword.
const car1 = new Car("Toyota", "Camry", 2024);
const car2 = new Car("Honda", "Accord", 2025);

console.log(car1); // Output: Car { make: 'Toyota', model: 'Camry', year: 2024 }
console.log(car2); // Output: Car { make: 'Honda', model: 'Accord', year: 2025 }

✅ Advantages

  • Reusable blueprint for creating multiple similar objects
  • Encapsulates properties and methods in one place
  • Improves code organization and modularity
  • Works well with prototypes for method sharing
  • Reusable code: Constructors are a great way to avoid repeating code when you need to create multiple similar objects.
  • Encapsulation: They group related data and functionality together, which improves the organization and modularity of your code.
  • Customization: Arguments can be passed to a constructor to create unique instances with different initial properties.
  • Familiar pattern: For developers with a background in other object-oriented languages, the concept is familiar and intuitive.

❌ Disadvantages

  • Methods defined inside constructor are duplicated for each object
  • Less memory-efficient compared to prototype-based methods
  • Can be confusing for beginners due to use of this and new
  • Verbose syntax: The standard way to add methods to constructor functions involves using the prototype, which can be less intuitive and more verbose than the ES6 class syntax.
  • Performance overhead for methods: If you define methods directly inside the constructor function, a new copy of that method is created for every instance, which is inefficient. The more memory-efficient approach is to define methods on the constructor's prototype.
  • Forgetting new: Calling a constructor function without the new keyword is a common mistake that can lead to bugs, as this will refer to the global object instead of a new object.
  • Coupling: This approach can tightly couple the calling code to the new requirement. Refactoring to a more flexible "factory function" can become a breaking change for existing callers.

📌 When to use

  • When you need to create multiple objects with the same structure
  • For defining custom object types in plain JavaScript
  • When building models in object-oriented programming style
  • Legacy codebases: If you are working in an older JavaScript environment or a project that already uses constructor functions, continuing to use them maintains a consistent style.
  • Deep understanding of prototypes: As constructor functions expose the underlying prototypal inheritance, they are excellent for gaining a deeper understanding of how JavaScript's object model works.
  • Simplicity: For very simple object patterns where you don't need complex inheritance, a constructor function can be a quick and efficient solution.

🚫 When not to use

  • For one-off objects — use object literals instead
  • When using ES6 classes — prefer class syntax for modern code
  • In functional programming patterns where object instantiation isn't needed
  • Modern development: For all new code, the ES6 class syntax is the recommended approach. It offers cleaner syntax for creating objects and handling inheritance.
  • Avoiding the new keyword: If you prefer not to require the new keyword to create objects, use a factory function instead.
  • Complex inheritance: Managing inheritance chains with constructor functions and prototypes can become complex and difficult to maintain compared to the extends keyword in ES6 classes.

Best practices and precautions

  • Use prototype for methods: To save memory, define methods on the constructor's prototype rather than inside the constructor function.
function Car(make, model) {
  this.make = make;
  this.model = model;
}

Car.prototype.drive = function() {
  console.log(`Driving the ${this.make} ${this.model}.`);
};

const myCar = new Car("Ford", "Focus");
myCar.drive(); // Output: "Driving the Ford Focus."
  • Capitalize constructor names: Follow the naming convention of capitalizing the first letter of a constructor function to make it immediately clear that it should be called with new.
  • Add a check for new (pre-ES6): In environments before ES6, add a check inside your constructor to ensure it was called with new. This was a common defensive pattern.
  • Use ES6 classes: In modern JavaScript, use the class keyword. It provides a cleaner, more readable syntax for constructors and inheritance while still using the same prototypal inheritance system under the hood.
Back to Index
Previous Error Handling in Javascript (try catch) Classes-ES6-Javascript Next
*
*