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(); }