我以为我已经理解了闭包的概念,但是下面的代码 我的表现令人惊讶:
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已成为静态变量。 更改通话顺序不会改变结果。
答案 0 :(得分:4)
当您更改prototype
时,您正在更改给定班级的所有实例的function
,包括已存在的 。
因此,当你打电话......
A.prototype.getX2 = function () { return x; }
您为a1
的现有A
实例设置了该值。因此,您最终会得到以下伪代码:
<all instances of A>.getX2 = function () {
return <latest value of x passed to A constructor>;
}
答案 1 :(得分:2)
此处的静态成员是A.prototype.getX2
。对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
答案 2 :(得分:2)
每次创建新的A时,你都会定义两次getX2。该函数的结果将始终是最后的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,它就会按预期工作。
答案 3 :(得分:1)
你写过
function A(x)
{
this.getX1 = function () { return x; }
A.prototype.getX2 = function () { return x; }
}
此构造函数每次都会覆盖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(); }