🔗
Prototypes
intermediatePrototypes are JavaScript's mechanism for inheritance. Every object has a hidden [[Prototype]] link to another object. When you access a property, JS looks up the prototype chain until it finds it or reaches null.
🎮Interactive Visualization
Look up:
Heap Memory (Prototype Chain)
dog
name:"Rex"
bark:fn()
__proto__: → Animal.prototype
↓ __proto__
Animal.prototype
speak:fn()
eat:fn()
__proto__: → Object.prototype
↓ __proto__
Object.prototype
toString:fn()
hasOwnProperty:fn()
__proto__: → null
↓ __proto__
null
End of chain
Key Insight: Prototype Chain: JS walks up __proto__ links until it finds the property or hits null.
Key Points
- Every object has a [[Prototype]] (accessible via __proto__ or Object.getPrototypeOf)
- Property lookup walks up the prototype chain
- Functions have a .prototype property used for constructor instances
- Object.create() creates objects with a specific prototype
- ES6 classes are syntactic sugar over prototypes
💻Code Examples
Basic Prototype Chain
const animal = {
eats: true,
walk() {
console.log("Walking");
}
};
const dog = {
barks: true
};
dog.__proto__ = animal;
dog.barks; // true (own property)
dog.eats; // true (from prototype)
dog.walk(); // "Walking" (from prototype)JS walks up __proto__ links to find properties
Simple Object Literal
const obj = { x: 1 };
// All objects inherit from Object.prototype
obj.__proto__ === Object.prototype // true
// That's why we can use:
obj.toString(); // "[object Object]"
obj.hasOwnProperty("x"); // true
// These methods come from Object.prototypeObject literals inherit from Object.prototype
Object.create()
const parent = {
greet() {
console.log("Hello from " + this.name);
}
};
const child = Object.create(parent);
child.name = "Child";
child.greet(); // "Hello from Child"
// Object.create() sets the prototype
Object.getPrototypeOf(child) === parent // trueCreate object with specific prototype
Property Shadowing
const parent = {
name: "Parent",
greet() {
return "Hi from " + this.name;
}
};
const child = Object.create(parent);
child.name = "Child"; // shadows parent.name
child.greet(); // "Hi from Child"
// child.name shadows parent.name
// but greet() is still from parentChild property hides parent property
Constructor Function
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
console.log("Hi, I'm " + this.name);
};
const alice = new Person("Alice");
const bob = new Person("Bob");
alice.greet(); // "Hi, I'm Alice"
bob.greet(); // "Hi, I'm Bob"
// Both share the same greet method!
alice.greet === bob.greet // trueInstances inherit from Constructor.prototype
hasOwnProperty Check
const parent = { inherited: true };
const child = Object.create(parent);
child.own = true;
// hasOwnProperty: only own properties
child.hasOwnProperty("own"); // true
child.hasOwnProperty("inherited"); // false
// 'in' operator: checks entire chain
"own" in child; // true
"inherited" in child; // true
// Useful for safe iteration
for (let key in child) {
if (child.hasOwnProperty(key)) {
console.log(key); // only "own"
}
}hasOwnProperty checks only object, "in" checks chain
Object.create(null)
// Normal object has prototype
const normal = {};
normal.toString; // [Function]
// Null prototype = truly empty
const dict = Object.create(null);
dict.toString; // undefined
// Safe dictionary (no collisions)
dict["hasOwnProperty"] = "safe!";
dict.hasOwnProperty; // "safe!"
// With normal object this would
// shadow the built-in methodNo prototype = no inherited methods, safe dictionaries
Class Syntax (ES6)
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + " makes a sound");
}
}
class Dog extends Animal {
speak() {
console.log(this.name + " barks");
}
}
const dog = new Dog("Rex");
dog.speak(); // "Rex barks"
// Classes are syntactic sugar!
// Under the hood: prototypesClasses are syntactic sugar over prototypes
Common Mistakes
- Confusing __proto__ with .prototype
- Modifying Object.prototype (affects all objects!)
- Not understanding that arrays/functions are also objects with prototypes
Interview Tips
- Draw the prototype chain for a given object
- Explain the difference between __proto__ and .prototype
- Know how ES6 classes relate to prototypes