JavaScriptclosures和原型

我以为我已经理解了闭包的想法,但是下面的代码对我来说意外的performance:

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 

我可以理解原型方法与实例方法的行为不同,但是这看起来像x已经成为一个静态variables。 更改通话顺序不会改变结果。

当您更改prototype您将更改给定类的所有实例( 包括已经存在的实例)的function

所以当你打电话…

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

您正在为A的现有a1实例设置它。 所以有效地结束了以下伪代码:

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

这里的静态成员是A.prototype.getX2 。 第二次调用A.prototype.getX2 = function () { return x; } A.prototype.getX2 = function () { return x; } (由于var a2 = new A(2); )取代了第一个。 要理解它,你可以颠倒实例的顺序:

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

那么你将有:

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

你定义了两次getX2,每次你创build一个新的A.该函数的结果将永远是最后一个X.考虑重写你的代码,如下所示:

 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​​​ 

这样,你只定义一次getX2,并按预期工作。

你写

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

这个构造A.prototype.getX2每次覆盖A.prototype.getX2

所以第一

 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. 

所以应该是这样的

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