Constructor Functions & The 4-Step new Mechanism
new operator ke peeche kya hota hai? Sirf ek line likhte ho new User(), par V8 ke andar 4 step ka khel chalta hai.
The new operator is not magic — it follows a precise 4-step mechanism that V8 executes every time you write new Constructor():
Step 2: Set the object's prototype (__proto__) to the constructor's .prototype property.
Step 3: Execute the constructor function with this pointing to the new object.
Step 4: If the constructor returns an object, use that. Otherwise, return the new object.
This mechanism powers every object created with new — including ES6 class instances. Classes use the exact same 4 steps under the hood.
function User(name) {
this.name = name;
// Implicitly returns 'this'
}
// What happens: const sai = new User('Sai');
// Step 1: const obj = {};
// Step 2: obj.__proto__ = User.prototype;
// Step 3: User.call(obj, 'Sai'); // this = obj
// Step 4: return obj;
// Implementing new manually
function customNew(Constructor, ...args) {
const obj = {}; // Step 1
Object.setPrototypeOf(obj, Constructor.prototype); // Step 2
const result = Constructor.apply(obj, args); // Step 3
return result instanceof Object ? result : obj; // Step 4
}
const ali = customNew(User, 'Ali');
console.log(ali.name); // 'Ali'
console.log(ali instanceof User); // trueIf you call a constructor function without the new keyword, this points to globalThis (which is window in browsers). This is one of JavaScript's most dangerous traps.
In sloppy mode: this.name = name creates a global variable on window! Silent bug — no error, no warning.
In strict mode: this is undefined, so this.name = name throws a TypeError immediately. Much safer!
function User(name) {
// Safety check
if (!new.target) {
throw new Error('User must be called with new!');
// Or auto-fix: return new User(name);
}
this.name = name;
}
// BAD: Calling without new (sloppy mode)
// const badUser = User('Sai'); // Pollutes window.name in sloppy!
// GOOD: Using new
const goodUser = new User('Sai'); // Safe!
console.log(goodUser.name); // 'Sai'
new keyword, it generates a 'Construct' bytecode instead of a 'Call' bytecode. 'Construct' allocates a new JSObject, sets its prototype, and runs the function. Classes in ES6 use the exact same 'Construct' bytecode, which is why classes throw if called without new.Constructors have a bizarre return value rule that can cause confusing bugs:
If a constructor returns a PRIMITIVE (string, number, boolean), the primitive is IGNORED. The new object is returned normally.
If a constructor returns an OBJECT (object, array, function), that object replaces the new object entirely!
function Normal() {
this.value = 1;
// Implicitly returns this
}
console.log(new Normal().value); // 1
function ReturnsPrimitive() {
this.value = 2;
return 42; // Primitive! Ignored!
}
console.log(new ReturnsPrimitive().value); // 2 (primitive ignored)
function ReturnsObject() {
this.value = 3;
return { hacked: true }; // Object! Overrides this!
}
const weird = new ReturnsObject();
console.log(weird.value); // undefined (this was thrown away!)
console.log(weird.hacked); // true (returned object used)
The instanceof operator checks if Constructor.prototype exists anywhere in the object's prototype chain. But it has important caveats:
It does NOT check if the object was actually created by the constructor. Any object with the right prototype in its chain passes the check.
It can be faked by changing __proto__ or Constructor.prototype.
Cross-realm issue: An array from an iframe fails instanceof Array of the parent window (different constructor).
function Animal() {}
const dog = new Animal();
console.log(dog instanceof Animal); // true
console.log(dog instanceof Object); // true (Animal.prototype is an object)
// Faking instanceof
const cat = {};
Object.setPrototypeOf(cat, Animal.prototype);
console.log(cat instanceof Animal); // true! But cat wasn't created by new Animal.
// Cross-realm issue
// const iframeArray = iframe.contentWindow.Array;
// console.log([] instanceof iframeArray); // false! Different Array constructor.
// Better type checking for primitives
console.log(typeof 'hello' === 'string'); // true
console.log('hello' instanceof String); // false (primitive, not object)
Array.isArray() for arrays and typeof for primitives. For custom types, Symbol.hasInstance lets you customize instanceof behavior — but that's advanced territory. For most cases, instanceof works fine within a single realm.Every function (except arrow functions) gets a .prototype property automatically when defined. This is the shared blueprint for all instances created via new.
The prototype object has a .constructor property that points back to the original function — creating a circular link.
Methods should be added to the prototype so all instances share one copy (saves memory). Properties specific to each instance belong inside the constructor.
function User(name) {
// Own properties (unique per instance)
this.name = name;
}
// Shared methods (one copy for all instances)
User.prototype.greet = function() {
return 'Hi, I am ' + this.name;
};
const sai = new User('Sai');
const ali = new User('Ali');
console.log(sai.greet()); // 'Hi, I am Sai'
console.log(ali.greet()); // 'Hi, I am Ali'
// Both share the EXACT SAME greet function in memory
console.log(sai.greet === ali.greet); // true
// The constructor link
console.log(sai.constructor === User); // true
this.greet = function(){}), every instance gets its own copy — wastes memory. Prototype methods are shared by all instances.Lo kar liya — Key Points:
- ✅ The
newoperator does 4 things: creates object, sets __proto__, binds this, returns object (unless constructor returns an object) - ✅ Calling a constructor without
newpollutes the global object in sloppy mode; usenew.targetto guard - ✅ If a constructor returns an object, that object replaces the new object; primitives are ignored
- ✅
instanceofchecks the prototype chain, not the actual constructor; it can be faked and fails across realms - ✅
Constructor.prototypeis the shared blueprint for all instances; put methods there to save memory
Want to track your progress?
Log in to save your place and pick up where you left off.
Progress track karna chahte ho?
Login karo apni progress save karne ke liye aur jahan chhoda tha wahan se shuru karo.
Login