Search code examples
javascriptoopprototypal-inheritance

inheritance using prototype in javascript


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


Solution

  • 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.