Javascript继承 - 构造函数中声明的对象是在实例之间共享的吗?

时间:2009-09-28 07:22:32

标签: javascript inheritance

我在没有Prototype / jQuery的情况下在JavaScript中进行面向对象的编程(我将jQuery用于其他东西)。到目前为止,它一直运行良好,但我遇到了继承问题。基本上,当我在构造函数中声明对象时,它们在实例之间共享。以下是一些示例代码:

    A = function()
    {
        this.y = new Array();
    }

    A.prototype.doStuff = function(n)
    {
        this.y.push(n);
    }

    B = function()
    {
    }

    B.prototype = new A();

    var b1 = new B();
    var b2 = new B();

    b1.doStuff(100);
    b2.doStuff(200);

    console.log("b1:");
    console.log(b1);
    console.log("b2:");
    console.log(b2);

这会为[100, 200]b1输出数组b2。我想要的是b1b2y拥有自己独立的数组。我该怎么做?

(PS。我认为Prototype的类系统内置了一些东西。但是我宁愿不重写我的一堆代码来使用该类系统)

2 个答案:

答案 0 :(得分:7)

问题是你的A构造函数只对所有B实例运行一次,因此this.y只是对一个数组的引用。从B对它的任何引用都将通过原型链解析为单个中心A引用,该引用只有一个y。这是一个非常有用的功能,只是不是你想在这里做的。

答案是将构造与初始化分开;构造函数设置中心资源,初始化程序初始化实例。这就是我在JavaScript中看到的大多数“类”实现所处理的问题。为了实现这一点,你必须为层次结构中的每个级别提供一种方法来调用前一级别的初始化程序(这对其他方法也很有用) - 例如,超级调用。

Supercalls就是为什么你可能会更好地使用像Prototype这样的东西:它们很难做得很好,并且非常容易陷入“孙子”问题 - 一个解决方案这似乎有效,但最终只能使用Parent< -Child结构,而不是Parent< -Child< -GrandChild结构。

但是,如果您要进行自己的继承机制,那么来自我可怜的博客的this post on supercalls可能会有所帮助,因为我会深入研究其中的一些问题。它需要Prototype的继承机制的简化版本,解构它,并讨论一种做超级调用的方法,它没有我与Prototype当前超级调用有一些问题。这可能会帮助您在自己的机制中完成它们。

答案 1 :(得分:2)

B.prototype = new A();

这为每个B只创建一个A实例。

您可能会考虑做某事

B = function()
{
  this.$super = new A();
}


B.prototype.doStuff = function()
{
  return this.$super(args);
}


C = function ()
{
  this.$super = new B();
}


C.prototype.doStuff = function()
{
  return this.$super(args);
}

C.prototype.whoIsMyGrandParent = function()
{
  return this.$super.$super;
}

Javascript没有真正的继承