How does
thiswork in JavaScript?thisis decided by how a function is called, not where it is defined. By priority:new Fn(): the new object.call,applyorbind: the object passed.obj.fn():obj.- a plain
fn():undefinedin strict mode, the global object otherwise.
Arrow functions skip all four and use the surrounding
this.JavaScript'use strict'; function who() { return this?.name; } const user = { name: 'Ada', who }; class Person { constructor(name) { this.name = name; } } console.log(user.who(), who(), who.call({ name: 'Grace' }), new Person('Linus').name);More in the this keyword.
What is the difference between
call,applyandbind?All three set
this.callandapplyinvoke at once, with arguments listed or as an array;bindreturns a new function withthisand any given arguments fixed.JavaScript'use strict'; function introduce(greeting, punct) { return `${greeting}, I am ${this.name}${punct}`; } const ada = { name: 'Ada' }; console.log(introduce.call(ada, 'Hi', '.')); console.log(introduce.apply(ada, ['Hello', '.'])); const bound = introduce.bind(ada, 'Hey'); console.log(bound('?'));Use
bindto pass a method as a callback without losing its object.What happens to
thiswhen you copy a method out of its object?JavaScript'use strict'; const user = { name: 'Ada', getName() { return this?.name; }, }; const getName = user.getName; console.log(user.getName(), getName(), getName.call(user));thisis set at call time. The copiedgetName()is a plain call, so in strict modethisisundefined;call(user)sets it back. Passinguser.getNameas a callback hits the same bug; fix it withbind.What is the prototype chain?
Every object links to a prototype, another object or
null. A property the object lacks is looked up along that chain untilnull, which is how inheritance works.JavaScriptconst animal = { eats: true, describe() { return `${this.name} eats: ${this.eats}`; }, }; const dog = Object.create(animal); dog.name = 'Rex'; console.log(dog.describe()); console.log(Object.getPrototypeOf(dog) === animal, Object.hasOwn(dog, 'eats')); console.log(Object.getPrototypeOf(Object.prototype));Reads go up the chain; an assignment creates an own property unless the chain holds a setter or read-only property of that name. See prototypes.
What is the difference between
__proto__andprototype?prototypeis a property of constructors and classes: what instances made withnewinherit from.__proto__is an accessor onObject.prototypethat exposes an object's actual prototype, so in browsers and Node.jsinstance.__proto__ === Constructor.prototype.JavaScriptfunction User(name) { this.name = name; } const u = new User('Ada'); console.log(Object.getPrototypeOf(u) === User.prototype, User.prototype.constructor === User); console.log(typeof User.prototype, u.prototype);__proto__is deprecated; useObject.getPrototypeOfandObject.setPrototypeOf.Are JavaScript classes different from constructor functions?
Mostly no: a class is syntax over constructor functions and prototypes, and
typeofa class is'function'. The differences are that class bodies are strict, methods are non-enumerable, classes neednew, and declarations sit in the temporal dead zone.JavaScriptclass Shape { constructor(name) { this.name = name; } area() { return 0; } toString() { return `${this.name} with area ${this.area()}`; } } class Circle extends Shape { constructor(r) { super('circle'); this.r = r; } area() { return Math.round(Math.PI * this.r ** 2); } } console.log(String(new Circle(2))); console.log(typeof Shape, Object.getPrototypeOf(Circle.prototype) === Shape.prototype);In a subclass, call
super()before touchingthis.What does the
newkeyword do? Can you implement it?new Fn(args)creates an empty object, sets its prototype toFn.prototype, callsFnwiththisbound to it, and returns it, unlessFnreturns an object of its own.JavaScriptfunction myNew(Ctor, ...args) { const obj = Object.create(Ctor.prototype); const result = Ctor.apply(obj, args); return result !== null && (typeof result === 'object' || typeof result === 'function') ? result : obj; } function User(name) { this.name = name; } User.prototype.greet = function () { return 'hi ' + this.name; }; const u = myNew(User, 'Ada'); console.log(u.greet(), u instanceof User);Get the last step right: a returned primitive is ignored, a returned object replaces the instance.
How do you make private properties in JavaScript?
Use private fields, written with
#. Only code inside the class body can reach them; outside access is a syntax error.JavaScriptclass Account { #balance = 0; deposit(n) { this.#balance += n; return this; } get balance() { return this.#balance; } } const acc = new Account().deposit(100); console.log(acc.balance, Object.keys(acc).length, '#balance' in acc);The field is invisible to
Object.keys,JSON.stringifyand a stringincheck, so this prints100 0 false.What is the difference between
constandObject.freeze?conststops the variable from being reassigned;Object.freezemakes the object itself read-only, one level deep.JavaScript'use strict'; const config = Object.freeze({ port: 3000, db: { host: 'localhost' } }); try { config.port = 8080; } catch (e) { console.log(e.constructor.name); } config.db.host = 'remote'; console.log(config.port, config.db.host, Object.isFrozen(config.db));Writing to a frozen property throws in strict mode and is ignored otherwise, and
config.dbis still writable.How does
instanceofwork in JavaScript? Can you implement it?obj instanceof Ctorwalksobj's prototype chain and istrueif it meetsCtor.prototype. It checks the chain, not how the object was built.JavaScriptfunction 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; } class Animal {} class Dog extends Animal {} const rex = new Dog(); console.log(myInstanceOf(rex, Animal), rex instanceof Animal); console.log(myInstanceOf('hi', String), 'hi' instanceof String); console.log(Object.create(null) instanceof Object, Array.isArray([]));Primitives are never instances, and an array made in another frame (an iframe) fails
instanceof Array, so useArray.isArray. A class can override the check withstatic [Symbol.hasInstance].
JavaScript this, Prototypes and Classes Interview Questions
How this is bound, how the prototype chain works, and what classes add.
10 questions