The prototype property is a reference. Our Accountant object’s prototype contains a reference to the Person prototype. This has two very important implications. Firstly, if a change is made to a prototype, all objects with that prototype get the same change. If we have 2 Accountant objects that we made from our Accountant prototype, and we add an “age” property to the prototype then both Accountant objects will have an accessible age property.
This where the second implication kicks in. The age property has been added to the Accountant prototype, not the object itself. However, if we check the object for the age property it will return that property. This is because JavaScript will traverse the prototype chain looking for any reference made to the requested property. We can access the age property from our object because the JavaScript engine will check the prototype for the age property once it finds it missing on the object. Likewise, if we had added the age property to the Person prototype, our object would still respond as if it had the age property. The engine will have checked the object, the Accountant prototype, and then the Person prototype. The JavaScript engine will keep opening Russian dolls until it finds the property requested, or reaches the final doll inside that doesn’t open. This is true for functions as well since all functions are handled the same as properties.
There are performance and maintenance pitfalls that all JavaScript developers should be cognizant of from this behavior. For example, it is strongly discouraged to modify the prototypes of native objects like String or Array. Making any change to a native prototype could inadvertently affect code on the page that isn’t yours, or cause a change that isn’t expected, and therefore isn’t caught until it is too late. On the performance side, an exceptionally long prototype chain can slow down the application as the engine navigates it’s way down the chain looking for a property.
The next version of JavaScript, version 6 (more accurately ECMAScript 6), will be adding some syntactic sugar, and some additional functionality, to bring this relationship into a more traditional model. The newer version adds the ability to define classes and subclasses, including keywords like extend and super(). However, under the hood this is still doing the prototype chain operations while adding some protections to avoid the pitfalls mentioned above.
Understanding prototypes and the way that JavaScript uses them is important for all JavaScript developers to understand. Many nuances of the language begin to make a little more sense when you understand the details.