3

I have following code. Why do all the three objects refer to the same array while the string variable is independent? How can I fix it without explicitly adding: function B(){this.arr = [];}

function A(){
  this.text = "";
  this.arr = [];

  this.action = function(){
    this.text+="z";
    this.arr.push(1); 
  }

  this.test = function(){
    console.log(this.text+"|"+this.arr);
  }
}

function B(){
    
}

B.prototype = new A();        
B.prototype.constructor = B;
var B1 = new B();
var B2 = new B();
var B3 = new B();

B1.action();
B2.action();
B3.action();
B1.test(); //z|1,1,1
B2.test(); //z|1,1,1
B3.test(); //z|1,1,1
sheplu
  • 2,937
  • 3
  • 24
  • 21
Ilya
  • 59
  • 8
  • You should use `function B() { A.call(this) }` instead of repeating everything that the parent constructor does. – Bergi Sep 04 '17 at 20:15

1 Answers1

0

An explanation would be:

Prototypes are live chains between objects. Because B's prototype is a single tone instance of A, the array prop is passed by reference. This means that for each B instance we have access to the same A instance on the prototype. This might sound confusing at first but that's the magic of prototypes in JavaScript.

This is the caveat of prototypal inheritance. Anything on the prototype will be passed down to each instance. To maintain different instances of the attribute we initialise our object's attributes in the constructor.

When working with objects in JS (like arrays), they are passed by reference.

To make use of JS's prototype system I would suggest something like so:

function A(){
  this.text = "";

  this.action = function(){
    this.text+="z";
    this.arr.push(1); 
  }

  this.test = function(){
    console.log(this.text+"|"+this.arr);
  }
}

function B(){
    this.arr = [];
}

B.prototype = new A();

This way we reuse the methods from the "parent" and have a localised array in our "child". At a first glance this might look as a classic OOP inheritance case but it is a bit different.

If you want to read more about prototypes in JS I recommend this article

Hope this helps.

Andrei CACIO
  • 2,101
  • 15
  • 28
  • thanks for the explanation. The problem is, I also have C,D,E that inherit from A and I don't want to duplicate my code. I think I have to use Parasitic inheritance instead. https://stackoverflow.com/a/2107586/5902472 – Ilya Sep 04 '17 at 20:04
  • No, don't use this code. [It's still wrong](https://stackoverflow.com/a/17393153/1048572?Benefits-of-using-Object.create-for-inheritance) – Bergi Sep 04 '17 at 20:14
  • @Bergi thank you for the reference, I was simply explaining why it didn't work before. I do agree that is not the best way to achieve prototypal inheritance. – Andrei CACIO Sep 05 '17 at 05:49