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

时间:2012-10-29 18:31:57

标签: javascript oop inheritance

我创建了一个如下对象。

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'

然后我创建了另一个继承自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'

我不知道为什么。我最近一直在阅读很多关于闭包和原型继承的内容,我怀疑我已经把它弄得一团糟。因此,非常感谢任何有关此特定示例为何如此工作的指针。

2 个答案:

答案 0 :(得分:3)

只有一个BaseObject实例,所有TestObject都继承该实例。不要使用实例来创建原型链!

你想要的是:

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

有关new问题的详细说明,请参阅JavaScript inheritance: Object.create vs newCorrect javascript inheritanceWhat is the reason to use the 'new' keyword at Derived.prototype = new Base。另请查看Crockford's Prototypal inheritance - Issues with nested objects

答案 1 :(得分:2)

将原型继承视为仅处理对象而没有类的概念。在您的代码中,您有一个BaseObject对象,该对象具有prop属性。您有2个其他对象从该对象的1个实例扩展,但该属性属于原始对象。如果您需要每个对象都有自己的副本,那么需要为它们提供一个为该对象初始化的不同变量(例如在它们的构造函数中)。

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