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

IT技术 javascript oop inheritance
2021-03-02 20:02:38

我创建了一个如下所示的对象。

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个回答

只有一个BaseObject实例所有的TestObjects 都继承自。不要使用实例来创建原型链!

你想要的是:

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

JavaScript的继承:VS的Object.create新的正确的Javascript继承什么是使用在Derived.prototype“新”关键字=新基地的理由为有问题的详细说明new另请查看Crockford 的原型继承 - 嵌套对象的问题

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

顺便说一句,Java 风格的访问器在 JavaScript 中是矫枉过正的(如果需要,您可以本地拦截访问)并且可以进一步混淆这些问题,因为它们的行为会有所不同。

所以 TestObject 需要有它自己的prop属性。从 TestObject 继承的任何东西也需要它自己的prop属性?等等?
2021-04-18 20:02:38
是的,就像经典继承一样,但是您必须通过确保以正确的方式调用构造函数或使用 mixin 来以不同的方式实现它,以便所有实例数据都在它所属的地方。
2021-04-23 20:02:38