On this page
Polyfill: the new operator and instanceof
Last reviewed 22 Sept 2026
Problem
Implement myNew(Constructor, ...args) that behaves like new Constructor(...args), and myInstanceOf(obj, Constructor) that behaves like obj instanceof Constructor:
function Person(name) { this.name = name; }Person.prototype.hi = function () { return 'hi ' + this.name; };
const p = myNew(Person, 'Asha');p.hi(); // "hi Asha"myInstanceOf(p, Person); // truemyInstanceOf(p, Object); // truemyInstanceOf(p, Array); // falseClarifying questions
- What if the constructor returns an object?
newreturns that object instead of the new instance. - What if it returns a primitive? Ignored — the new instance is returned.
- Does
myInstanceOfneed to handle primitives? Yes:myInstanceOf(1, Number)isfalse. - Support
Symbol.hasInstance? Mention it; implement only if asked.
Approach
new F(...args) does four things: create an empty object, link its prototype to F.prototype, call F with this set to the new object, and return that object unless F returned an object of its own. instanceof walks the prototype chain of obj looking for F.prototype.
Step-by-step build
Step 1 — the four steps of new
function myNew(Ctor, ...args) { const obj = Object.create(Ctor.prototype); // 1 + 2: new object, linked prototype const result = Ctor.apply(obj, args); // 3: run the constructor with this = obj return result !== null && (typeof result === 'object' || typeof result === 'function') ? result // 4: an explicitly returned object wins : obj;}Step 2 — validate the constructor
Arrow functions and methods have no prototype and cannot be constructed.
if (typeof Ctor !== 'function' || !Ctor.prototype) throw new TypeError(Ctor + ' is not a constructor');Step 3 — instanceof
function myInstanceOf(obj, Ctor) { if (obj === null || (typeof obj !== 'object' && typeof obj !== 'function')) return false; let proto = Object.getPrototypeOf(obj); while (proto !== null) { if (proto === Ctor.prototype) return true; proto = Object.getPrototypeOf(proto); } return false;}Final code
function myNew(Ctor, ...args) { if (typeof Ctor !== 'function' || !Ctor.prototype) { throw new TypeError(String(Ctor) + ' is not a constructor'); } const obj = Object.create(Ctor.prototype); const result = Ctor.apply(obj, args); const isObject = result !== null && (typeof result === 'object' || typeof result === 'function'); return isObject ? result : obj;}
function myInstanceOf(obj, Ctor) { if (typeof Ctor !== 'function') throw new TypeError("Right-hand side of 'instanceof' is not callable"); if (obj === null || (typeof obj !== 'object' && typeof obj !== 'function')) return false; let proto = Object.getPrototypeOf(obj); while (proto !== null) { if (proto === Ctor.prototype) return true; proto = Object.getPrototypeOf(proto); } return false;}Edge cases
- Constructor returns
{}→ that object; returns42or'x'→ ignored. - Constructor returns a function → the function is returned (functions are objects).
myNewon an arrow function throws, likenew.myInstanceOf(Object.create(null), Object)→false: that object has no prototype chain.- Classes:
myNewusesCtor.apply, which throws forclassconstructors (“cannot be invoked without new”). UseReflect.construct(Ctor, args)if classes must be supported — say so.
Follow-ups
Symbol.hasInstance:instanceoffirst checksCtor[Symbol.hasInstance]— how would you add it?- Why is
instanceofunreliable across iframes? Each realm has its ownArray.prototype; useArray.isArray. - What does
new.targetgive inside a constructor? The constructor thatnewwas applied to — used in the bind polyfill.
Common mistakes
- Returning
result || obj, which returns a primitive like42when the constructor returns one. - Setting
obj.__proto__after calling the constructor, so methods are missing during construction. - Comparing against
Ctorinstead ofCtor.prototypeininstanceof. - Not handling primitives on the left of
instanceof.
Related
- Concepts: prototypes, constructors and
thisin the JavaScript track. - Previous: Object.assign and Object.create.