Search code examples
javascriptprototypeprototype-chain

Behavior of primitive types in prototypes


Every instance have a link to prototype of the constructor using which it is created. So every instance shares the prototype members. If a change to the shared prototype member is made through one instance it is reflected to all other instances. Why this doesn't seem to work with primitive types as can be seen below:

//creating an empty object type
function OBJTYPE(){};

//adding primitive value and reference value as a memeber to 
//the prototype of the object type
OBJTYPE.prototype.value = 0;
OBJTYPE.prototype.arr = ["red","green","blue"];

//creating instances of the object type
var obj1 = new OBJTYPE();
var obj2 = new OBJTYPE();

//outputting the prototype members through both the instances     
document.write(obj1.value + "<br />");  //0
document.write(obj2.value + "<br />");  //0
document.write(obj1.arr + "<br />");    //red,green,blue
document.write(obj2.arr + "<br />"); //red,green,blue

//changing value of primitive member
obj1.value = 1;  //creates a new instance property

//modifying the reference type member - pushing a value on the array
obj1.arr.push("black"); //modifies the prototype property

//outputting the prototype members through both the instances     
document.write(obj1.value + "<br />"); //1 //.value from instance
document.write(obj1.__proto__.value + "<br />"); //0 //.value from prototype
                                                 //works in Firefox, Safari, and Chrome
document.write(obj2.value + "<br />"); //0 //.value from prototype

document.write(obj1.arr + "<br />");   //red,green,blue,black
document.write(obj2.arr + "<br />");   //red,green,blue,black

As you can see above changing value of primitive member creates a new instance property called value on obj1, instead of overwriting same named property in the prototype. Thus when accessing obj1.value property it returns instance property which masks the prototype property. That's why the two instances instances show different values of value.

However this doesn't reference type do not behave similarly as can be seen from above. Why?


Solution

  • You were pushing to the array, not assigning a new array like you did with the primitive value. This will work as expected:

    obj1.value = 1; 
    obj1.arr = [];
    

    Note that setting a value never sets on the prototype, but on the object itself.