Step 1 of 7 · Reading · ~4 min
Learn
Objects in Depth
The Prototype Chain
Every JavaScript object can point at another object, its prototype, and property lookup follows those links. The class keyword (taught in the custom-error-classes lesson) is a friendlier way to set them up, not a different system. By the end of this lesson you can draw the chain behind any object, predict where a property will be found, and explain what instanceof really tests.
Objects link to other objects
Reading a property walks outward: the object itself, then its prototype, then that object's prototype, and so on until it finds the name or reaches null (the end), which gives undefined.
Writing never walks. bike.wheels = 2 creates an own property on bike that shadows the inherited one; vehicle is untouched, and delete bike.wheels would reveal 4 again. Methods found up the chain still run with this set to the object you called them on (bike), which is why describe printed 2.
To ask whether a name is the object's own or inherited, use Object.prototype.hasOwnProperty.call(obj, "name"), and Object.getPrototypeOf(obj) to step up one link.
The top of the chain
A plain {} has Object.prototype as its prototype, which holds toString, hasOwnProperty and the other things every object seems to have. Its own prototype is null. You can build an object that has no prototype at all:
Constructor functions build the same links
A function called with new (rule 3 of the previous lesson) links the new object to the function's prototype property. Setting that property up by hand shows the chain being built:
The chain is c -> Circle.prototype -> Shape.prototype -> Object.prototype -> null. Only name is an own property of c; methods live once on the prototypes and every instance shares them. Two similar names cause endless confusion: Circle.prototype is a property of the constructor, naming the object that future instances will link to, while Object.getPrototypeOf(c) is the link of an instance. What new Circle("disc") does is: create an empty object linked to Circle.prototype, run the constructor with this set to it, and return it. A class ... extends declaration builds exactly these links with less typing.
instanceof and isPrototypeOf
c instanceof Shape asks: is Shape.prototype somewhere along c's chain? It is, so true. Shape.prototype.isPrototypeOf(c) asks the same question about any two objects, with no constructor involved.
A shared-prototype trap
Everything on a prototype is shared. That is perfect for methods and a bug for mutable data:
Per-instance data belongs in the constructor (this.items = []).
Common mistakes
- Putting arrays or objects on a prototype and sharing them by accident.
- Changing
Object.prototype, which affects every object in the program. - Expecting
obj.x = 1to change the prototype'sx. It adds an own property. - Using
for...inand being surprised it lists inherited enumerable names;Object.keysgives own names only. - Calling
obj.hasOwnPropertyon an object made withObject.create(null). - Mixing up
Fn.prototypeand the actual prototype of an instance.
Your exercise
The starter builds a family of objects with Object.create from a small description and asks questions about them. You write the three helpers that walk the chain by hand.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…