javascript闭包和原型

javascript闭包和原型,javascript,node.js,closures,prototype,Javascript,Node.js,Closures,Prototype,我想我已经理解了闭包的思想,但是下面的代码 对我来说,行为令人惊讶: 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.getX

我想我已经理解了闭包的思想,但是下面的代码 对我来说,行为令人惊讶:

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已成为一个静态变量。
更改调用顺序不会更改结果。

此处的静态成员是
A.prototype.getX2
。对
A.prototype.getX2=function(){return x;}
(由于
var a2=newa(2);
)的第二次调用将替换第一次调用。要理解它,您可以颠倒实例化的顺序:

var a2 = new A(2);
var a1 = new A(1);
然后您将有:

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

更改
原型
时,您正在更改给定类的所有实例(包括已经存在的实例)的
函数

所以当你打电话给

A.prototype.getX2 = function () { return x; }
您正在为
A
的现有
a1
实例设置该值。因此,实际上您将得到以下伪代码:

<all instances of A>.getX2 = function () {
    return <latest value of x passed to A constructor>;
}
.getX2=函数(){
返回;
}
您已经编写了

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

每次创建一个新的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,它就可以正常工作