Let’s demystify JavaScript’s ‘new’ keyword

by Cynthia Lee

Let’s demystify JavaScript’s ‘new’ keyword

Over the weekend, I completed Will Sentance’s JavaScript: The Hard Parts. It might not sound like the most glorious way to spend a weekend, but I actually found it pretty fun and relaxing to complete the course. It touched on functional programming, higher-order functions, closures, and asynchronous JavaScript.

For me, the highlight of the course was how he expanded on the JavaScript approaches to Object-Oriented Programming (OOP) and demystified the magic behind the new operator. I now have a well-rounded understanding of what goes on under the hood when the new operator is used.

Object-Oriented Programming in JavaScript

Object-Oriented Programming (OOP) is a programming paradigm based on the concept of “objects.” Data and functions (attributes and methods) are bundled within an object.

An object in JavaScript is a collection of key-value pairs. These key-value pairs are properties of the object. A property can be an array, a function, an object itself or any primitive data type such as strings or integers.

What techniques do we have in our JavaScript toolbox for object creation?

Let’s assume that we are creating users in a game that we just designed. How would we store user details such as their names, points, and implement methods such as an increment in points? Here are two options for basic object creation.

To create a user, you would now enter the information in parameters of the function.

let user1 = createUser("Bob", 5);
user1.increment();

However, the increment function in the example above is just a copy of the original increment function. This is not a good way to write your code, as any potential changes to the function will need to be done manually for each object.

Solution 2 — Use the prototypal nature of JavaScript

Unlike object-oriented languages such as Python and Java, JavaScript does not have classes. It uses the concept of prototypes and prototype chaining for inheritance.

When you create a new array, you automatically have access to built-in methods such as Array.join, Array.sort, and Array.filter. This is due to the fact that array objects inherit properties from Array.prototype.

Every JavaScript function has a prototype property, which is empty by default. You can add functions to this prototype property, and in this form, it is known as a method. When an inherited function is executed, the value of this points to the inheriting object.

When the user1 object was created, a prototype chain bond with userFunction was formed.

When user1.increment() is in the call stack, the interpreter will look for user1 in the global memory. Next, it will look for the increment function, but will not find it. The interpreter will look at the next object up the prototype chain and will find the increment function there.

Solution 3 — new and this keywords

Thenew operator is used to create an instance of an object which has a constructor function.

When we call the constructor function with new, we automate the following actions:

A new object is created

It binds this to the object

The constructor function’s prototype object becomes the __proto__ property of the new object

It returns the object from the function

This is fantastic, because the automation results in less repetitive code!

By using the prototype pattern, each method and property is added directly on the object’s prototype.

The interpreter will go up the prototypal chain and find the increment function under the prototype property of User, which itself is also an object with the information inside it. Remember — All functions in JavaScript are also objects. Now that the interpreter has found what it needs, it can create a new local execution context to run user1.increment().

Side note: Difference between __proto__ and prototype

If you are already getting confused about __proto__ and prototype, don’t worry! You are far from the only one to be confused about this.

Prototype is a property of the constructor function that determines what will become the __proto__ property on the constructed object.

So, __proto__ is the reference created, and that reference is known as the prototype chain bond.

Solution 4 — ES6 ‘syntactic sugar’

Other languages allow us to write our shared methods within the object “constructor” itself. ECMAScript6 introduced the class keyword, which allows us to write classes that resemble normal classes of other classical languages. In reality, it is syntactic sugar over JavaScript’s prototypal behavior.

In solution 3, the associated methods were precisely implemented using User.prototype.functionName. In this solution, the same results are achieved but the syntax looks cleaner.

Conclusion

We have now learned more about the different options we have in JavaScript to create objects. While class declarations and thenew operator are relatively easy to use, it is important to understand what is automated.

To recap, the following actions are automated when the constructor function is called with new:

A new object is created

It binds this to the object

The constructor function’s prototype object becomes the __proto__ property of the new object

Our mission: to help people learn to code for free. We accomplish this by creating thousands of
videos, articles, and interactive coding lessons - all freely available to the public. We also have
thousands of freeCodeCamp study groups around the world.

Donations to freeCodeCamp go toward our education initiatives, and help pay for servers, services,
and staff.