Think about a prototype as a linkage between two objects; the linkage is hidden behind the scenes, though there are ways to expose and observe it. This prototype linkage occurs when an object is created; it’s linked to another object that already exists.

    A series of objects linked together via prototypes is called the “prototype chain.”

    The purpose of this prototype linkage (i.e., from an object B to another object A) is so that accesses against B for properties/methods that B does not have, are delegated to A to handle. Delegation of property/method access allows two (or more!) objects to cooperate with each other to perform a task.

    Consider defining an object as a normal literal:

    The homework object only has a single property on it: topic. However, its default prototype linkage connects to the Object.prototype object, which has common built-in methods on it like toString() and valueOf(), among others.

    We can observe this prototype linkage delegation from homework to Object.prototype:

    homework.toString() works even though homework doesn’t have a toString() method defined; the delegation invokes Object.prototype.toString() instead.

    To define an object prototype linkage, you can create the object using the Object.create(..) utility:

    Figure 4 shows how the three objects (otherHomework, homework, and Object.prototype) are linked in a prototype chain:

    Fig. 4: Objects in a prototype chain

    Delegation through the prototype chain only applies for accesses to lookup the value in a property. If you assign to a property of an object, that will apply directly to the object regardless of where that object is prototype linked to.

    Consider:

    The assignment to topic creates a property of that name directly on ; there’s no effect on the topic property on homework. The next statement then accesses otherHomework.topic, and we see the non-delegated answer from that new property: "Math".

    Figure 5 shows the objects/properties after the assignment that creates the otherHomework.topic property:

    3 objects linked, with shadowed property

    The topic on otherHomework is “shadowing” the property of the same name on the homework object in the chain.

    NOTE:
    Another frankly more convoluted but perhaps still more common way of creating an object with a prototype linkage is using the “prototypal class” pattern, from before class (see Chapter 2, “Classes”) was added in ES6. We’ll cover this topic in more detail in Appendix A, “Prototypal ‘Classes’”.

    this Revisited

    We covered the this keyword earlier, but its true importance shines when considering how it powers prototype-delegated function calls. Indeed, one of the main reasons this supports dynamic context based on how the function is called is so that method calls on objects which delegate through the prototype chain still maintain the expected this.

    Consider:

    The two objects jsHomework and mathHomework each prototype link to the single homework object, which has the study() function. jsHomework and mathHomework are each given their own property (see Figure 6).

    Fig. 6: Two objects linked to a common parent

    jsHomework.study() delegates to homework.study(), but its this (this.topic) for that execution resolves to jsHomework because of how the function is called, so this.topic is "JS". Similarly for mathHomework.study() delegating to homework.study() but still resolving this to mathHomework, and thus this.topic as "Math".

    The preceding code snippet would be far less useful if this was resolved to homework. Yet, in many other languages, it would seem this would be homework because the study() method is indeed defined on homework.