What is the use of the new operator in JavaScript
`new F(args)` does four things: (1) create an empty object whose prototype is `F.prototype`, (2) call `F` with `this` bound to the new object, (3) if `F` returns an object, use that; otherwise use the new object, (4) return the result. Powers class instantiation and constructor functions. Arrow functions can't be `new`'d.
What new actually does
For new F(...args):
- Create a fresh object whose internal [[Prototype]] is
F.prototype. - Call
Fwiththisset to that new object and...args. - If
Fexplicitlyreturns an object, the expression evaluates to that object; otherwise it evaluates to the new object. - The result has
instance instanceof F === true(because prototype chain).
As a polyfill
function myNew(Ctor, ...args) {
const obj = Object.create(Ctor.prototype); // step 1
const result = Ctor.apply(obj, args); // step 2
return (result && typeof result === "object") ? result : obj; // step 3
}With a class
class Foo { constructor(x) { this.x = x; } }
const f = new Foo(1);
f instanceof Foo; // true
Object.getPrototypeOf(f) === Foo.prototype; // trueReturning an object overrides
function Quirky() { return { custom: true }; }
const q = new Quirky();
q.custom; // true
q instanceof Quirky; // false — we replaced thisRarely useful; mostly a curiosity. Builder patterns sometimes exploit it.
Forgetting new
function Person(name) { this.name = name; }
const p = Person("Sam"); // no new
// In strict mode: TypeError because this is undefined.
// In sloppy: this is globalThis — globalThis.name = "Sam". Disaster.This is why ES6 class throws if called without new — safer.
Arrow functions can't be new'd
Arrow functions have no [[Construct]] method:
const F = () => {};
new F(); // TypeError: F is not a constructorSame for methods defined with shorthand inside an object literal.
new.target
Inside a constructor, new.target is the function that new was called with (the most-derived class). Useful for:
class Abstract {
constructor() {
if (new.target === Abstract) throw new Error("Abstract class");
}
}When you need new
- Class instantiation (
new MyComponent()). - Constructor functions (legacy code).
- Built-ins:
new Date(),new Map(),new Set(),new Promise(),new URL(),new Error().
Some built-ins also work without new (Error("...")); convention varies.
Modern advice
- Use
classso misuse throws. - Prefer factory functions (
createUser(...)) when you don't need a prototype chain. - Don't write
function Foo() { this.x = ...}constructor functions in new code.
Interview framing
"new F(args) creates an object whose prototype is F.prototype, calls F with this bound to that object, and returns the new object (unless F returns a different object). The polyfill is Object.create(F.prototype) then F.apply(obj, args). Forgetting new on an ES5 constructor function is a silent disaster — this becomes undefined (strict) or globalThis (sloppy). class solves this by throwing without new. Arrow functions can't be new'd — they have no [[Construct]] internal method. Inside a constructor, new.target is the most-derived class — useful for abstract-class checks."
Follow-up questions
- •Why can't arrow functions be new'd?
- •What does new.target do?
- •Why does class throw without new?
Common mistakes
- •Forgetting new on a constructor function.
- •Returning a non-object expecting it to override.
- •Trying to new an arrow function.
Performance considerations
- •new'd objects share prototype methods (memory efficient). Avoid creating arrow methods on instance if memory is tight.
Edge cases
- •Returning an object overrides the new instance.
- •Built-ins behave differently with vs without new.
- •new.target undefined when not called with new.
Real-world examples
- •new Date(), new URL(), new Map, new Promise, class instantiation everywhere.