The Prototype Chain
JavaScript objects can inherit properties and methods from other objects.
This inheritance system is based on prototypes.
Every normal object has an internal link to another object called its prototype.
When JavaScript cannot find a property directly on an object, it looks up the prototype chain.
Own Properties
An own property is a property that exists directly on an object.
const user = {
name: "Alice",
};
console.log(user.name); // Alicename is an own property of user.
You can check this with Object.hasOwn().
console.log(Object.hasOwn(user, "name")); // trueInherited Properties
Objects can also access inherited properties.
const user = {
name: "Alice",
};
console.log(user.toString); // [Function: toString]You did not define toString on user.
So where did it come from?
It comes from Object.prototype.
Most normal objects inherit from Object.prototype.
Property Lookup
When you access a property, JavaScript searches in this order:
- Check the object itself.
- If not found, check the object's prototype.
- Continue up the prototype chain.
- Stop when the chain reaches
null.
Example:
const user = {
name: "Alice",
};
console.log(user.name); // found on user
console.log(user.toString); // found on Object.prototype
console.log(user.missing); // undefinedIf JavaScript reaches the end and does not find the property, it returns undefined.
The Prototype Chain Diagram
user
-> Object.prototype
-> nullThis means:
user inherits from Object.prototype.
Object.prototype is the end of the normal object chain.The final prototype is null.
Checking a Prototype
Use Object.getPrototypeOf() to inspect an object's prototype.
const user = {
name: "Alice",
};
const prototype = Object.getPrototypeOf(user);
console.log(prototype === Object.prototype); // trueThis is the modern way to inspect a prototype.
Arrays Have Their Own Prototype Chain
Arrays are objects too.
const numbers = [1, 2, 3];
console.log(numbers.map); // [Function: map]The map method is not stored directly on every array.
It comes from Array.prototype.
Array chain:
numbers
-> Array.prototype
-> Object.prototype
-> nullThat is why arrays can use both array methods and object methods.
Functions Have Prototypes Too
Functions are objects in JavaScript.
function greet() {
return "Hello";
}
console.log(greet.name); // greet
console.log(greet.call); // [Function: call]Function methods like call, apply, and bind come from Function.prototype.
Function chain:
greet
-> Function.prototype
-> Object.prototype
-> nullShadowing Prototype Properties
If an object has its own property with the same name as an inherited property, the own property wins.
const user = {
toString() {
return "Custom user string";
},
};
console.log(user.toString()); // Custom user stringJavaScript finds toString directly on user, so it does not use Object.prototype.toString.
This is called shadowing.
in vs Object.hasOwn()
The in operator checks own and inherited properties.
const user = {
name: "Alice",
};
console.log("name" in user); // true
console.log("toString" in user); // trueObject.hasOwn() checks only own properties.
console.log(Object.hasOwn(user, "name")); // true
console.log(Object.hasOwn(user, "toString")); // falseUse the right check for the question you are asking.
Prototype Chain and Methods
Prototype methods are shared.
Every array does not store its own copy of map, filter, and reduce.
Instead, arrays share methods through Array.prototype.
const first = [1, 2, 3];
const second = [4, 5, 6];
console.log(first.map === second.map); // trueThis sharing is memory-efficient.
Best Practices
Use Object.getPrototypeOf() to inspect prototypes.
Use Object.hasOwn() when you only care about direct properties.
Remember that arrays and functions are objects with prototype chains.
Avoid modifying built-in prototypes like Array.prototype or Object.prototype.
Keep prototype concepts in mind when learning classes.
Common Mistakes
Mistake 1: Thinking Every Method Is Stored Directly on the Object
const numbers = [1, 2, 3];
console.log(Object.hasOwn(numbers, "map")); // falsemap comes from Array.prototype.
Mistake 2: Confusing in With Own Property Checks
"toString" in {};This is true because toString is inherited.
Use:
Object.hasOwn({}, "toString"); // falseMistake 3: Modifying Built-In Prototypes
Array.prototype.last = function () {
return this[this.length - 1];
};This can cause conflicts and bugs in shared code.
Avoid modifying built-in prototypes in normal application code.
Quick Check
What does this log?
const user = {
name: "Alice",
};
console.log(Object.hasOwn(user, "name"));
console.log(Object.hasOwn(user, "toString"));It logs:
true
falsename is an own property.
toString is inherited.
Summary
The prototype chain is JavaScript's object inheritance system.
- Objects can inherit from other objects.
- Own properties live directly on the object.
- Inherited properties come from the prototype chain.
- JavaScript searches upward when a property is missing.
Object.getPrototypeOf()inspects an object's prototype.inchecks own and inherited properties.Object.hasOwn()checks only own properties.- Arrays and functions also use prototype chains.