Skip to main content

Command Palette

Search for a command to run...

The new Keyword in JavaScript

Published
6 min read
The new Keyword in JavaScript
A
my work defines me

Ever wondered how you can stamp out multiple, similar objects without writing { ... } over and over? Or how to create "types" of objects like User, Product, or Car, each with its own properties and methods? That's where the new keyword and constructor functions come in!

Think of the new keyword as the "on switch" for building custom objects from a blueprint. Without it, you're just calling a regular function; with it, you're initiating a powerful, step by step object creation process.

Here is what we’ll cover in this guide:

  • Exactly what the new keyword does

  • What constructor functions are and how to write them

  • A step-by-step breakdown of the object creation process

  • The magic of how new automatically links prototypes

  • Understanding instances created from constructor functions


The Problems with Manually Creating Objects

Before we dive into new, let's quickly understand the issue it solves. Imagine creating multiple user objects manually:

// Manual User Creation (Tedious & Repetitive)
const user1 = {
  name: 'Abhinav',
  role: 'Developer',
  greet: function() {
    console.log(`Hi, I'm \({this.name}, a \){this.role}.`);
  }
};

const user2 = {
  name: 'Guest',
  role: 'Moderator',
  greet: function() {
    console.log(`Hi, I'm \({this.name}, a \){this.role}.`);
  }
};

// ... Imagine doing this for hundreds of users!
// Problems: Code Duplication, Hard to Maintain, Inefficient Memory (duplicated methods)

As you can see, you're redefining properties (name, role) and methods (greet) repeatedly. It's inefficient, error prone, and a total headache if you ever need to change how users work.


Constructor Functions: The Blueprint

A constructor function is your object blueprint. It's essentially a regular function that you intend to use with the newkeyword to create objects. By convention, their names start with a capital letter (like User instead of user) to remind everyone to use new.

Simple Constructor Example:

// Constructor Function for Users
function User(name, role) {
  // 1. (Implicitly) a new, empty object is created (this = {})
  
  // 2. We add properties to this new object using `this`
  this.name = name;
  this.role = role;
  
  // 3. We *could* add methods here, but prototypes are better (we'll see later!)
  this.greet = function() {
    console.log(`Hi, I'm \({this.name}, a \){this.role}.`);
  };
  
  // 4. (Implicitly) the function returns the newly created object (unless it explicitly returns a different object)
} 

Now, instead of writing out { ... } manually, we can just call our blueprint function:

// Using the Constructor Function (Wait, what did we forget?)
const abhinav = User('Abhinav', 'Developer'); // This is a problem!
console.log(abhinav); // undefined! And we've polluted the global object with name/role!

Wait, it didn't work as expected! Calling User like a regular function (without new) doesn't create and return a new object. In fact, this inside the function will refer to the global object (window in browsers), setting name and role on the window itself definitely not what we wanted!


The new Keyword: Activating the Blueprint

This is where the magic of the new keyword comes into play. When you put new before a function call, everything changes:

// Creating Objects correctly with `new`
const abhinav = new User('Abhinav', 'Developer');
const guest = new User('Guest', 'Moderator');

console.log(abhinav.name); // Abhinav
console.log(guest.name);   // Guest
abhinav.greet(); // Hi, I'm Abhinav, a Developer.
guest.greet();   // Hi, I'm Guest, a Moderator.

Success! We have clean, distinguishable objects (abhinav, guest) with the correct properties, all stamped out efficiently from our single User blueprint. These objects are called instances of the User constructor.


What Does new Actually Do? (Step-by-Step)

So, what exactly happens behind the scenes when you use new? It’s not magic; it’s a specific, four-step process initiated by JavaScript:

  1. Creates a blank, plain JavaScript object: It implicitly creates a new, empty object (think {}). Inside the constructor function, this now refers to this specific new object.

  2. Links (sets the prototype of) this new object to the constructor function's prototype property: This is key for shared methods and property inheritance (more on this visual later!). Basically, it connects the new instance to the broader "family tree" defined by the constructor.

  3. Executes the constructor function body with the given arguments: The code inside your constructor function (this.name = name; this.role = role;) now runs. Since this is our new object, it's populated with these specific values.

  4. Returns this (the newly created object) automatically: After running the function body, new implicitly ensures that the newly created and populated object is returned as the result of the new ConstructorCall(...) expression. (Unless the constructor function explicitly returns its own object, in which case that object is returned instead, but that's advanced and usually best avoided for simplicity!)


new and Prototypes: Shared Methods, Not Duplicated

Remember when I said adding methods directly in the constructor wasn't ideal? That's because every single instance (user1, user2, user3, etc.) would get its own separate copy of the exact same greet function, wasting memory.

The solution? Add methods to the constructor function's prototype property. This is a special object that all instances created with new will automatically share and inherit from all thanks to Step 2 of the new process!

// Constructor Function
function User(name, role) {
  this.name = name;
  this.role = role;
  // greet is gone from here!
}

// Adding Shared Method to the Prototype
User.prototype.greet = function() {
  console.log(`Hi, I'm \({this.name}, a \){this.role}.`);
};

const abhinav = new User('Abhinav', 'Developer');
const guest = new User('Guest', 'Moderator');

abhinav.greet(); // Works! Uses inherited greet from User.prototype
guest.greet();   // Also works! Uses the *same* inherited greet function

Now, User.prototype holds the greet method. When we call abhinav.greet(), JavaScript first looks for greet directly on the abhinav object. It's not there. But because new created the prototype link, JavaScript automatically looks on abhinav's prototype which is User.prototype finds greet, and executes it. Every user instance now shares this one single greet function, significantly saving memory.


Conclusion

The new keyword is a fundamental concept in JavaScript for efficiently creating and organizing custom objects. It unlocks the power of constructor functions and automatically handles the intricate details of object initialization, including the critical linking of prototypes for shared behaviors. While understanding prototypes can get deep, mastering new gives you the tools to write cleaner, more reusable, and better-structured code, moving you away from manual object duplication and towards scalable, robust applications. Next time you need multiple users, products, or cars, remember your constructor blueprint and the new keyword!