为什么我的JavaScript对象属性被其他实例覆盖?

我创build了一个如下的对象。

var BaseObject = function(){ var base = this; base.prop; base.setProp = function(val){ base.prop = val; } } 

当我调用setProp方法时,我得到以下内容。

 var a = new BaseObject(); var b = new BaseObject(); a.setProp("foo"); b.setProp("bar"); console.log(a.prop); // outputs 'foo' console.log(b.prop); // outputs 'bar' 

然后我创build了另一个inheritance自BaseObject对象。

 var TestObject = function(){ // do something } TestObject.prototype = new BaseObject(); 

当我这样做时,我得到了一个我并不期待的结果。

 var a = new TestObject(); var b = new TestObject(); a.setProp("foo"); b.setProp("bar"); console.log(a.prop); // outputs 'bar' console.log(b.prop); // outputs 'bar' 

我不知道为什么。 最近我一直在阅读关于闭包和原型inheritance的知识,我怀疑我已经把它弄糊涂了。 所以任何指针为什么这个特定的例子工作方式,将不胜感激。

只有一个BaseObject实例从中inheritance所有的TestObject 。 不要使用实例来创build原型链!

你想要的是:

 var TestObject = function(){ BaseObject.call(this); // give this instance own properties from BaseObject // do something } TestObject.prototype = Object.create(BaseObject.prototype); 

请参阅JavaScriptinheritance:Object.create与新的 , 正确的JavaScriptinheritance和什么原因使用Derived.prototype = new的“新”关键字新基地的new问题的详细解释。 也看看Crockford的Prototypalinheritance – 嵌套对象的问题

把原型inheritance看成是单纯地处理对象而没有类的概念。 在你的代码中你有一个具有prop属性的BaseObject对象。 您有2个其他对象从该对象的1个实例扩展而来,但该属性属于原始对象。 如果你需要每个对象拥有自己的副本,那么他们需要被赋予一个独立的variables,这个variables是为那个对象初始化的(比如在构造函数中)。

另外,Java风格的访问器在JavaScript中是过度的(如果需要,你可以本地拦截访问),并且可以进一步混淆这些问题,因为它们的行为不同。