Objectsintermediate
Prototype Chain Explained
How objects inherit properties and methods from other objects through an internal link called the prototype, forming a chain up to Object.prototype.
Every object has a hidden link to another object. Looking up a property follows that chain until it is found or the chain ends.
The prototype chain is like an org chart for answering questions: you ask your direct teammate (own properties) first; if they don't know, you escalate up to their manager (prototype), then their manager's manager, until someone up the chain has the answer or you reach the CEO (Object.prototype) with nowhere further to go.
Key Concepts
1
const animal = { speak() { return 'noise'; } };
const dog = Object.create(animal);
dog.name = 'Rex';2
dog.name // own property
dog.speak() // not own -- found on animal
dog.toString // found on Object.prototype3
dog -> animal -> Object.prototype -> null4
That is inheritance in JavaScript. There are no classes underneath — class is syntax over this.
class
5
Where the chain comes from.
function Dog(name) { this.name = name; }
Dog.prototype.speak = function () { return 'woof'; };6
const d = new Dog('Rex');
Object.getPrototypeOf(d) === Dog.prototype // true7
new creates an object whose prototype is the constructor's .prototype property. The two are different
things with confusingly similar names:
new.prototype
8
Dog.prototype the object instances will inherit from
d.__proto__ the link on the instance itself9
Methods live on the prototype for a reason. One copy, shared by every instance:
10
// one function, ten thousand dogs
Dog.prototype.speak = function () {};11
// ten thousand functions
function Dog() { this.speak = function () {}; }12
Own against inherited.
d.hasOwnProperty('name') // true
d.hasOwnProperty('speak') // false -- inherited
'speak' in d // true -- in checks the chain13
Object.keys(d) // own enumerable only
for (const k in d) // includes inherited enumerable14
That difference is why for...in over an object can surprise you, and why Object.keys is usually what was
meant.
for...inObject.keys
15
Shadowing. Assigning a property that exists on the prototype creates an own property; it does not modify
the prototype:
16
d.speak = () => 'custom'; // only this instance changes17
The practical points. Object.create(null) makes an object with no prototype at all — no toString, no
hasOwnProperty — which is the right base for a dictionary of arbitrary keys.
Object.create(null)toStringhasOwnProperty
18
And modifying built-in prototypes (Array.prototype.myHelper = ...) affects every array in the program,
including other libraries'. It is the reason that practice is universally discouraged.
Array.prototype.myHelper = ...
19
What the interviewer is probing.1. "What happens when you read a missing property?" Probing: lookup. Stalls: "It returns
undefined." Moves up: the engine walks the prototype chain and only returns undefined once it
reaches null at the end.
20
2. "What is the difference between prototype and __proto__?" Probing: the two names. Stalls:
"They are the same." Moves up: prototype is a property on constructor functions used for new
instances; __proto__ is the instance link to its prototype.
21
3. "Why is modifying Object.prototype dangerous?" Probing: global effect. Stalls: "It is
handy." Moves up: every object inherits it, so it can break for-in loops and third-party code
across the whole application.
22
4. "How do classes relate to prototypes?" Probing: the sugar. Stalls: "They are different
systems." Moves up: class syntax creates the same prototype links — methods live on the prototype
and extends sets the chain.