Class extension problem with javascript object prototype

I have this problem ... B is the base class, and A is the derived class ... An event, although A is derived from B, different objects of A point to the same object B.

I know that I assigned object B to prototype A to make A child of B.

But different objects A, they must have different address space for storing variables, right? Can you fix this?

function B(){ this.obj = {}; } function A(){ } A.prototype = new B(); var a = new A(); var b = new A(); var c = new A(); console.log(a.obj == b.obj); //prints true console.log(a.obj === b.obj); //prints true a.obj.name = "stackoverflow"; console.log(b.obj.name); //prints stackoverflow 

What change should I make to this code to give me the following result.

 a.obj === b.obj //must be false a instanceof A; //must be true a instanceof B; //must be true 
+6
source share
4 answers

That is why you should not have mutable values ​​(especially objects or arrays) in the prototype - the same value will be used for all instances of the object and can be changed in any of them. Here you can avoid the problem by using Object.create , which will not call constructor B when creating the prototype:

 A.prototype = Object.create(B.prototype); 

Constructor A should then call constructor B for each new object:

 function A() { B.call(this); } 

For browsers that do not support Object.create() , you can emulate it as indicated at http://javascript.crockford.com/prototypal.html .

+4
source

Values ​​are assigned by reference, and since all instances of A use the same instance of B as their prototype, they all refer to the same "B".

So this is exactly what is expected here. One way to solve this problem is to add (for example) an initialization method of class B, which you could call from constructor A.

You also cannot use the β€œnew B ()” to define the prototype and use Object.create instead. Object.create does not call constructor B, but then you can call the parent constructor from A.

 function A() { B.call(this); } 
+2
source

This is part of the prototypes in Javascript, I suggest you read this great thread .

+1
source

If you want instances of A to have the local obj property, add the property to A , not to B

 function B(){ } function A(){ this.obj = {}; // <<< this.obj here } A.prototype = new B(); var a = new A(); var b = new A(); var c = new A(); console.log(a.obj == b.obj); //=> prints false console.log(a.obj === b.obj); //=> prints false a.obj.name = "stackoverflow"; console.log(b.obj.name); //=> undefined 

another way to have a local obj property for instances of A is to use the setter method in prototype B :

 function B(){ B.prototype.setObj = function(obj){ this.obj = obj; return this; } } //... a.setObj({}).name = "stackoverflow"; console.log(a.obj.name); //=>prints stackoverflow console.log(b.obj.name); //=>undefined 
0
source

Source: https://habr.com/ru/post/891628/


All Articles