5

(I'm new to JavaScript). The following code:

function A() {
    console.log('Constructing A');
    this.a = new Array();
}
function B(x) {
    console.log('Constructing B');
    this.a.push(x);
    this.b = x;
}
B.prototype = new A();
b1 = new B(10);
b2 = new B(11);
console.log('b1', b1);
console.log('b2', b2);​

Results in b1 and b2 sharing single this.a array (but different this.b). It's like a shallow copy.

I don't quite understand what is the right way to create separate this.a arrays. I want them inherited because this is the logic of the code, besides I don't want to create them in each and every child object (and there are many child objects in my case).

Sandman4
  • 2,673
  • 2
  • 22
  • 18
  • see [Javascript property inheritance](http://stackoverflow.com/q/12027282/1048572) and [object members that are prototyped as arrays become shared by all class instances](http://stackoverflow.com/q/4425318/1048572) – Bergi Dec 16 '14 at 19:55

2 Answers2

3

I am very interested in the explanation of this problem. I've read @Niko`s duplicate question but it seems this is what makes the difference:

 function A() {
        console.log('Constructing A');
        this.a=new Array();
    }

    function B(x) {
        console.log('Constructing B');
        A.call(this); //--> calling the super() constructor creates a new array
        this.a.push(x);
    }

    B.prototype = new A();

    b1 = new B(11);
    b2 = new B(12);
    console.log(b1.a);
    console.log(b2.a);
Sandman4
  • 2,673
  • 2
  • 22
  • 18
Samson
  • 2,801
  • 7
  • 37
  • 55
  • Btw, why you need `B.prototype.constructor=B;` ? – Sandman4 Aug 26 '12 at 13:45
  • Actually I think `B.prototype = new A();` also does nothing here. We don't use inherited this.a because it results in shared array, instead we create a new array with super constructor. – Sandman4 Aug 26 '12 at 19:27
  • JS is a beautiful but strange language. Too flexible so that normal OOP models always can be realised using various language hacks. – Sandman4 Aug 26 '12 at 19:28
0

In your code:

> function A() {
>     console.log('Constructing A');
>     this.a = new Array();
> }
>
> function B(x) {
>     console.log('Constructing B');
>     this.a.push(x);
>     this.b = x;
> }
>
> B.prototype = new A();

This sets B's prototype as an instance of A. So all instances of B will have that instance of A on their [[Prototype]] chain.

In the B constructor, this references a new object that inherits from B.prototype, so this.a will reference the a property of B.prototype.

> b1 = new B(10);

So now B.prototype.a is [10].

> b2 = new B(11);

and now B.prototype.a is [10, 11].

RobG
  • 142,382
  • 31
  • 172
  • 209