Prototype in js
Prototypes & Prototype Chain in JavaScript
Delegation-based inheritance, [[Prototype]] links, and Object.create semantics.
The Royal Family Heirloom Recipe Book
JavaScript does not use classical inheritance where classes copy methods into instances. It uses Prototypal Delegation: objects contain an internal link `[[Prototype]]` to another object. If a property is missing on an object, the engine walks up the chain to resolve it.
The [[Prototype]] Internal Slot
Every JavaScript object has an internal hidden reference called `[[Prototype]]`, accessible via `Object.getPrototypeOf(obj)` or the historical `__proto__` accessor.
Function.prototype Property
Only functions have the `.prototype` property. When a function is called with `new Car()`, the new object's `[[Prototype]]` is set to `Car.prototype`.
The Prototype Chain Lookup
Accessing `obj.property` checks `obj` first. If missing, it checks `Object.getPrototypeOf(obj)`, then that object's prototype, continuing until reaching `Object.prototype.[[Prototype]] === null`.
Own Properties vs Inherited Properties
Check ownership using `Object.hasOwn(obj, "prop")`. The `in` operator checks both own and inherited prototype properties.
ES6 Classes are Syntactic Sugar
ES6 `class` and `extends` do not change how JavaScript works under the hood; they wrap standard prototypal delegation in cleaner syntax.
Prototypal delegation with constructor functions and Object.create:
function Animal(name) {
this.name = name;
}
// Shared method on prototype (saved once in memory for all instances)
Animal.prototype.speak = function() {
return `${this.name} makes a sound.`;
};
function Dog(name, breed) {
Animal.call(this, name); // Super constructor call
this.breed = breed;
}
// Wire the prototype chain: Dog.prototype delegates to Animal.prototype
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.bark = function() {
return `${this.name} barks loudly!`;
};
const buddy = new Dog("Buddy", "Golden Retriever");
console.log(buddy.bark()); // Found on Dog.prototype
console.log(buddy.speak()); // Delegated up to Animal.prototype
console.log(buddy.toString()); // Delegated up to Object.prototype
console.log("Own property breed:", Object.hasOwn(buddy, "breed")); // true
console.log("Own property speak:", Object.hasOwn(buddy, "speak")); // false (inherited)
Buddy barks loudly!
Buddy makes a sound.
[object Object]
Own property breed: true
Own property speak: false
Prototype Pollution
The Risk: Modifying `Object.prototype` directly (`Object.prototype.isAdmin = false`) injects properties into EVERY object across the entire runtime, leading to critical security vulnerabilities (CVEs).
The Fix: Never mutate built-in prototypes. Use `Object.create(null)` for pure dictionary lookups that have no prototype chain.
- ✓ JavaScript uses prototypal delegation, NOT classical copying.
- ✓ `obj.__proto__` points to the object's prototype; functions have `.prototype`.
- ✓ The chain ends at `Object.prototype.[[Prototype]] === null`.
- ✓ Use `Object.hasOwn(obj, key)` to verify own non-inherited properties.
- ✓ `Object.create(proto)` creates a new object with specified prototype.