Closing and prototyping javascript

I thought I understood the idea of ​​closing, but the following code behaves surprisingly for me:

function A(x) { this.getX1 = function () { return x; } A.prototype.getX2 = function () { return x; } } var a1 = new A(1); var a2 = new A(2); console.log ('a1.getX1()=%d', a1.getX1 ()); // 1 console.log ('a2.getX1()=%d', a2.getX1 ()); // 2 console.log ('a1.getX2()=%d', a1.getX2 ()); // 2 ??? console.log ('a2.getX2()=%d', a2.getX2 ()); // 2 

I could understand if the prototype methods would be different from the instances, but it looks like x has become a static variable. Reordering calls does not change the results.

+4
source share
4 answers

When you change prototype you change function instances for all of this class, including those that already exist.

So when you call ...

 A.prototype.getX2 = function () { return x; } 

You install this for an existing instance of a1 A This way you get the following pseudo-code:

 <all instances of A>.getX2 = function () { return <latest value of x passed to A constructor>; } 
+4
source

The static member is here A.prototype.getX2 . Second call of A.prototype.getX2 = function () { return x; } A.prototype.getX2 = function () { return x; } (due to var a2 = new A(2); ) replaces the first. To understand this, you can reverse the order of the instances:

 var a2 = new A(2); var a1 = new A(1); 

Then you will get:

 a1.getX1()=1 a2.getX1()=2 a1.getX2()=1 a2.getX2()=1 
+2
source

You define getX2 twice, each time you create a new A. The result for this function will always be the last X. Considering rewriting your code as follows:

 function A(x) { this.x = x; this.getX1 = function() { return this.x; } } A.prototype.getX2 = function() { return this.x; } var a1 = new A(1); var a2 = new A(2); console.log('a1.getX1()=%d', a1.getX1()); // 1 console.log('a2.getX1()=%d', a2.getX1()); // 2 console.log('a1.getX2()=%d', a1.getX2()); // 1 console.log('a2.getX2()=%d', a2.getX2()); // 2​​​ 

This way you only define getX2 once, and it works as expected.

+2
source

You wrote

 function A(x) { this.getX1 = function () { return x; } A.prototype.getX2 = function () { return x; } } 

This constructor overwrites A.prototype.getX2 each time.

So first

 var a1 = new A(1); // This invokes A and adds a function `getX2` to the prototype of `A`which returns `x` that is `1` var a2 = new A(2); // This invokes A and overwrites the function `getX2` in the prototype of `A` with a function which returns `x` that is `2` now. 

So it should be like

 function A(x) { this.getX1 = function () { return x; } } A.prototype.getX2 = function () { return this.getX1(); } 
+1
source

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


All Articles