如何为子原型创建不同的原型变量?

时间:2014-07-30 10:53:03

标签: javascript inheritance prototype chain

很抱歉这个令人困惑的问题标题。

简而言之,我希望能够将新的E()实例克隆到B和C的原型中,以便添加到B不会为C添加数组,反之亦然,但这些原型的所有实例都将如果它们是从同一个原型创建的,则可以访问相同的数组。

此代码尚未经过测试,但它显示了我用于扩展的方法,实际代码非常大。我能够在构造函数中实现这一点,但是在实例创建时初始化每个数组都有开销,我更倾向于每个原型都有一个共同的对象,理想情况下,该对象将从链的下一步继承它的属性(A in this例子)

function ObjectA() {
    Object.create(this.sharedVariable);
}

ObjectA.prototype = {
    sharedVariable: new E(); //returns []
}

function ObjectB() {
   ObjectA.call(this);
}

ObjectB.prototype = Object.create(ObjectA.prototype );
ObjectB.prototype.sharedVariable.push("B");

function ObjectC() {
   ObjectA.call(this);
}

ObjectC.prototype = Object.create(ObjectC.prototype );
ObjectC.prototype.sharedVariable.push("C");

var B = new ObjectB();
var C = new ObjectC();

1 个答案:

答案 0 :(得分:2)

假设我正确理解了您的问题,原型上的属性不会出于写入目的而共享。请考虑以下事项:

function A() { }
A.prototype = { v: 1 };
function B() { }
B.prototype = new A();
b = new B();
b.v = 99
delete b.v
b.v // 1

换句话说,即使b在其原型链中具有属性v,也通过A,当我们分配b.v时,分配到本地副本b。当我们删除实例属性时,对它的引用将恢复为引用原型链中的属性。

如果你想在实例之间共享一个变量,那就是某些模式中已知的静态变量,它将存在于A或B上,而不是它们的实例上。当然,它不能再被称为this.a,而必须是this.constructor.a

然而,这并不能轻易解决分享"共享" A上的(静态)变量,然后它的子类B也共享,因此B的实例b可以说this.constructor.v = 99并且在A的实例a上可以访问this.constructor.v的值。需要更多的机器才能实现这一目标。

一个通用(?)解决方案是按以下方式编写getter和setter:

function inherit_static_prop(parent, child, prop) {
  Object.defineProperty(child, prop, {
    get: function() { return parent[prop]; },
    set: function(v) { parent[prop] = v; }
  });
}

现在,你可以做到

function A () { }
A.v = 1;
function B () { }
inherit_static_prop(A, B, 'v');
b = new B();
b.constructor.v = 2;
a.constructor.v // 2

玩得开心。

OP评论

  

谢谢这是一个非常全面的答案,但我正在寻找的是   一种在定义B的原型时将v与A分离的方法   最初b.v = 2,a.v = 2,但如果我做b.prototype.setV(3)那么b.v =   3,a.v = 2.

如果我理解你的问题,我认为这将是正常行为:

function A() { }
A.prototype = { v: 1 };
function B() { }
B.prototype = new A();
b = new B();
b.v // 1
B.prototype.v = 3;
b.v = 3

换句话说,在定义B"的原型时,您不需要将A与A分离。如果您将相同名称的属性添加到B的原型中,它将自动解耦(阴影)。