7

I have an example class that has two properties: a variable and an object:

var Animal, a, b;

Animal = (function() {
  function Animal() {}

  Animal.prototype.priceb = 4;

  Animal.prototype.price = {
    test: 4
  };

  Animal.prototype.increasePrice = function() {
    this.price.test++;
    return this.priceb++;
  };

  return Animal;

})();

a = new Animal();

console.log(a.price.test, a.priceb); // 4,4
b = new Animal();
console.log(b.price.test, b.priceb); // 4,4
b.increasePrice();
console.log(b.price.test, b.priceb); // 5,5
console.log(a.price.test, a.priceb); // 5,4 !! not what I would expect. Why not 4,4?

For some reason, this seems to have a weird behavior. It looks like the class stores a reference to the object, so that it is shared across multiple instances.

How can I prevent that from happening?

Sebastian Hoitz
  • 9,343
  • 13
  • 61
  • 77

1 Answers1

7

The object (reference) that's in the prototype is indeed shared across the instances, until such time as the reference itself is modified, as opposed to the contents of the object.

The way around it is to give each object its own .price property within the constructor:

function Animal() {
    this.price = { test: 4 };
}

The (default) primitive value you've supplied in Animal.prototype.priceb is also initially shared across instances, except that as soon as you modify it the instance acquires its own copy that shadows the original value from the prototype.

Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • 1
    `"!? the instance acquires its own copy !?"` - ONLY if the property is not OBJECT (passed as reference) – bortunac Dec 05 '19 at 10:28
  • @bortunac even if the property is a reference to an object. If you have `Animal.prototype.obj = {}` and then overwrite `obj` in an _instance_ then that instance now has its own reference to a new object. – Alnitak Dec 06 '19 at 12:16
  • 1
    @Alnitak ... yes your right ... i just want to impose a usual mistake `o1= new Animal;o2=new Animal;o1.obj.prop1=1;`now `o2.obj.prop1 ===1 ;` – bortunac Dec 07 '19 at 12:25