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.