JS Prototype Chain
In this page:
object.__proto__
Object.getPrototypeOf(object);
Constructor.prototype.methodName = function() { };
What Is the Prototype Chain?
JavaScript objects can inherit properties from other objects. This lookup continues through a prototype chain.
This is the mechanism underlying every method call on a built-in type — array methods like .map() aren't stored on each array instance, they live once on Array.prototype.
Example: What Is the Prototype Chain?
const arr = [1, 2, 3];
console.log(arr.map === Array.prototype.map); // true, shared on the prototype
Checking Prototypes
You can inspect an object's prototype with Object.getPrototypeOf. It returns the object used for inheritance.
This is useful for confirming inheritance relationships at runtime, such as verifying an object was actually created via a particular constructor's prototype.
Example: Checking Prototypes
const arr = [];
console.log(Object.getPrototypeOf(arr) === Array.prototype);
Inherited Properties
A property may belong to the object itself or come from its prototype. The in operator checks both places.
Own properties always take precedence in this lookup, which is why you can override an inherited default by simply assigning a same-named property directly on the object.
Example: Inherited Properties
const obj = { greet() {} };
console.log("greet" in obj); // true, own property
console.log("toString" in obj); // true, inherited from prototype
Overriding Prototype Values
An object can define its own property with the same name as a prototype property. The own property is used first.
This lets a specific instance customize behavior — like a special-case object overriding a normally-shared method — without altering the shared prototype for every other instance.
Example: Overriding Prototype Values
// Declare the constant `proto`, set to `{ greet() { return "from prototype"; } }`
// Declare the constant `proto`, set to `{ greet() { return "from prototype"; } }`
const proto = { greet() { return "from prototype"; } };
// Declare the constant `obj`, set to `Object.create(proto)`
// Declare the constant `obj`, set to `Object.create(proto)`
const obj = Object.create(proto);
// Assign `() => "from own property"` to `obj.greet`
// Assign `() => "from own property"` to `obj.greet`
obj.greet = () => "from own property";
// Print `obj.greet()` to the console
// Print `obj.greet()` to the console
console.log(obj.greet());
Prototype Chain Lookup
JavaScript checks the object first, then its prototype, and keeps going until it reaches null.
Every prototype chain eventually terminates at Object.prototype and then null, which is why plain objects still inherit common methods like toString() by default.
Example: Prototype Chain Lookup
const obj = {};
console.log(Object.getPrototypeOf(Object.getPrototypeOf(obj))); // null, chain ends
console.log(obj.toString()); // inherited from Object.prototype
- Using
for...inon an object and being surprised that it also lists inherited properties. - Expecting
hasOwnPropertyandinto behave the same, wheninalso checks the prototype chain. - Changing
Object.prototypeor built-in prototypes, which affects every object in the program.
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: