JavaScript’s prototypal inheritance paradigm is easy to understand, but can lead to nasty surprises when it comes to non-primitive properties. While the issue I discuss here is purely a JavaScript one, the fact that the awesome CoffeeScript syntax make it so easy to implement classes and extend them leads developers to run more frequently into this kind of situations.
The Issue with Non-Primitive Properties
The issue can occur whenever we have a CoffeeScript class (or JavaScript
constructor) with a property which is not of a primitive type (basically
anything which is not number, string, boolean, null nor undefined).
For example, let’s have a class with an Array property:
1 2 | |
Now let’s create two instances, and let’s modify this non-primitive property on one of them:
1 2 3 4 5 6 7 8 9 10 11 12 | |
Changing one instance led to unwanted changes to other instances too! This
issue occurs because the needs property is stored in the shared
[[Prototype]].
Note that if we overwritten the property on one instance everything would have
been fine, since the overwritten value would live on that particular instance
only. But if we only modify the property, it stays in the [[Prototype]] and
the changes are shared among instances. This is why this issue can only occur
with non-primitive properties: primitives are immutable.
Hi! I’m Luca Ongaro, a Web Engineer from Italy currently living in Berlin. This is my blog, where I like to share random experiments and the results of some of my tinkering with Web technologies.