JavaScript Prototype Chain
The prototype chain is the sequence JavaScript follows to look up a property that an object does not own. It lets objects share behavior through other objects.
When you read `object.property`, JavaScript first checks whether `property` exists directly on `object`. If it does not, JavaScript checks the object's prototype, then that prototype's prototype, continuing until it finds the property or reaches `null`.
A prototype is another object linked to an object. You can inspect the link with `Object.getPrototypeOf()` and create an object with a chosen prototype using `Object.create()`.
If a property is found higher in the chain, it can be read through the original object, but it is not thereby added as an own property. For example, a method inherited from a prototype can be called on an object while remaining absent from that object's own properties.
JavaScript's `class` syntax uses prototypes: methods written in a class body are placed on that class's prototype and can be shared by its instances. Understanding the chain helps explain both class-based inheritance and property lookup in ordinary objects.
Key points
- Property lookup checks an object's own properties before its prototype.
- Lookup continues through prototypes until a match is found or the chain reaches `null`.
- An inherited property is accessible without becoming an own property.
- `Object.getPrototypeOf()` inspects an object's prototype; `Object.create()` can specify one.
- Methods defined in a class body are shared through the class's prototype.
Interview questions
What happens when JavaScript evaluates `obj.value` and `value` is not an own property?
JavaScript checks `obj` first. If the property is missing, it checks the object's prototype and continues along the prototype chain. The search stops at the first matching property or when it reaches `null`. If there is no match, the result is `undefined`.
How can you tell whether a property is inherited or belongs directly to an object?
A regular property read does not distinguish own from inherited properties. Use `Object.prototype.hasOwnProperty.call(obj, key)` to test whether the property belongs directly to `obj`. For example, an inherited method may be callable on `obj` while this check returns `false`. `Object.getPrototypeOf(obj)` can help inspect where inherited properties may come from.
What does it mean for a property on a prototype to be shadowed?
A property is shadowed when an object has its own property with the same name as one higher in its prototype chain. Reads on that object find the nearer own property first, so the prototype's property is not returned for that lookup. The inherited property is still present on the prototype. Removing the own property can make the inherited one visible again.
How do JavaScript classes use the prototype chain?
A class's non-static methods are placed on its prototype rather than copied onto every instance. Instances can find those methods through their prototype chain. This allows instances to share method definitions. The `class` syntax provides a structured way to work with this prototype-based mechanism.
What is the difference between an object's prototype and a constructor's `prototype` property?
An object's prototype is the object JavaScript consults during property lookup, and it can be inspected with `Object.getPrototypeOf(obj)`. A constructor function's `prototype` property is an object that is commonly used as the prototype for instances created with `new`. These ideas are related, but the names refer to different positions in the relationship. Checking `Object.getPrototypeOf(instance) === Constructor.prototype` is a common way to see that link for a typical constructor.