JavaScript new Operator
By Flavio Copes
Learn how the JavaScript new operator creates an object from a class or constructor function, including how arguments are passed to the constructor.
The JavaScript new operator is used to create a new object.
You follow new with the object class to create a new object of that type:
const date = new Date()
If the object constructor accepts parameters, we pass them:
const date = new Date('2019-04-22')
Date is built into the language, but new works the same way with constructors you write yourself.
Given an Object constructor like this:
function Car(brand, model) {
this.brand = brand
this.model = model
}
We initialize a new “Car” object using:
const myCar = new Car('Ford', 'Fiesta')
myCar.brand //'Ford'
myCar.model //'Fiesta'
What does new do behind the scenes?
When you run new Car('Ford', 'Fiesta'), JavaScript does a few things for you.
It creates a new empty object. It links that object to Car.prototype, so it inherits any method defined there. It runs the Car function with this pointing to the new object. Then it returns the object.
There’s one detail worth knowing: if the constructor explicitly returns an object, that object wins and replaces the one new created. A return with anything else, like a string or a number, is ignored. In practice, don’t return anything from a constructor and you’ll never think about this.
The prototype link is what makes instanceof work:
myCar instanceof Car //true
new with classes
The same operator works with class syntax, which is what I reach for today:
class Car {
constructor(brand, model) {
this.brand = brand
this.model = model
}
}
const myCar = new Car('Ford', 'Fiesta')
The constructor method plays the role the Car function played above. Same behavior, clearer syntax.
Watch out: forgetting new
Here’s the classic pitfall with constructor functions. Nothing stops you from calling one without new:
const myCar = Car('Ford', 'Fiesta')
myCar //undefined
The function runs like any regular function. this does not point to a fresh object, and since Car returns nothing, myCar ends up undefined. Worse, in non-strict mode this is the global object, so you quietly create global brand and model properties.
Classes protect you from this mistake. Calling a class without new throws an error right away:
class Car {}
Car() //TypeError: Class constructor Car cannot be invoked without 'new'
An immediate error beats a silent undefined every time. That’s one more reason to prefer classes over plain constructor functions.
Related posts about js: