0

I don't understand why the array is shared between two instances while the primitive type is not. Can someone please explain?

MyObject = function() {};
MyObject.prototype = {anArray : [],aString : ''};
var c1 = new MyObject();
c1.aString = 'a';
c1.anArray.push('a');
var c2 = new MyObject();
console.log(c2.aString);
console.log(c2.anArray);
antyrat
  • 27,479
  • 9
  • 75
  • 76
brad miley
  • 229
  • 2
  • 4
  • The primitive type *is* shared between both instances, but you've overwritten the `c1` object's own value. – zzzzBov May 08 '12 at 17:29

2 Answers2

2

Strings are immutable, Arrays are mutable. You're replacing the String, but modifying the Array.

You'll get the same behavior between Arrays and Strings if you overwrite the Array instead of modifying it.

MyObject = function() {};
MyObject.prototype = {anArray : [],aString : ''};

var c1 = new MyObject();
c1.aString = 'a';
c1.anArray = []
c1.anArray.push('a');

var c2 = new MyObject();
console.log(c2.aString); // ''
console.log(c2.anArray); // []

So it only makes sense to put an Object or Array on the prototype if you're planning on allowing all instances to observe changes to it. Otherwise, just put it directly on the instance.

MyObject = function() {
    this.anArray = [];
};
MyObject.prototype = {aString : ''};
cliffs of insanity
  • 3,683
  • 1
  • 16
  • 18
1

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.

Imp
  • 8,409
  • 1
  • 25
  • 36