When you assign
c1.aString = 'a'
you are not assigning to the aString
field in the prototype. A new field called aString
is created directly in the c1
object and hides the aString
field in the prototype.
Meanwhile, when you call
c1.anArray.push('a');
there is no anArray
field in c1
, so you're referencing the anArray
in prototype. You can test this by doing
c1.anArray = new Array();
and note that a new property anArray
is created in c1
, not interfering with anArray
in the prototype. In this case,
console.log(c1.anArray);
console.log(c2.anArray);
would have different outcome, as c2
would still refer to the anArray
in prototype.
If there is a field with the same name both directly in the object and in the prototype (or even further in the prototype chain), and you request a value of this field, the interpreter first looks directly into the object, only then up the prototype chain, until it finds the field somewhere.
However, if you assign a value to a field, it is always done directly in the object, never in its prototype.