Before classes there were constructor functions. Knowing what new does step by step explains classes, this, and a favourite interview question.
What new Fn(args) does
Create
A brand-new empty object is created.
Link
Its
[[Prototype]]is set toFn.prototype.Bind and run
Fnis called withthis= the new object and the given arguments.Return
If
Fnreturns an object, that object is the result; otherwise the new object is returned.
function myNew(Ctor, ...args) {
const obj = Object.create(Ctor.prototype); // steps 1 + 2
const result = Ctor.apply(obj, args); // step 3
return result !== null && typeof result === "object" ? result : obj; // step 4
}
function User(name) { this.name = name; }
User.prototype.hi = function () { return `hi ${this.name}`; };
const u = myNew(User, "Asha");
console.log(u, u.hi(), u instanceof User);User { name: 'Asha' } hi Asha trueReturning an object overrides this
function A() { this.x = 1; return { y: 2 }; }
function B() { this.x = 1; return 42; } // primitives are ignored
console.log(new A(), new B());{ y: 2 } B { x: 1 }Forgetting new
function Point(x) { this.x = x; }
try {
Point(5); // strict mode: this is undefined
} catch (e) {
console.log(e.message);
}
function SafePoint(x) {
if (!new.target) return new SafePoint(x); // guard with new.target
this.x = x;
}
console.log(SafePoint(5));Cannot set properties of undefined (setting 'x')
SafePoint { x: 5 }Inheritance the ES5 way
function Animal(name) { this.name = name; }
Animal.prototype.speak = function () { return `${this.name} makes a sound`; };
function Dog(name, breed) {
Animal.call(this, name); // "super(name)"
this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype); // link prototypes
Dog.prototype.constructor = Dog; // repair constructor
Dog.prototype.speak = function () {
return Animal.prototype.speak.call(this) + " (woof)";
};
const d = new Dog("Rex", "lab");
console.log(d.speak(), d instanceof Animal, d.constructor.name);Rex makes a sound (woof) true DogWhat happens when you call a function with new?