Javascript继承 - 在构造函数中声明的对象是在实例之间共享的吗? [英] Javascript inheritance -- objects declared in constructor are shared between instances?

查看:90
本文介绍了Javascript继承 - 在构造函数中声明的对象是在实例之间共享的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am doing Object Oriented programming in JavaScript without Prototype/jQuery (I use jQuery for other stuff). It has been working fine so far, but I ran into an issue with inheritance. Basically, when I declare objects in a constructor, they are shared between instances. Below is some sample code:

    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 。我想要的是 b1 b2 y <拥有自己独立的数组/ code>。我该如何解决这个问题?

This outputs an array [100, 200] for both b1 and b2. What I want is for b1 and b2 to have their own, separate arrays for y. How do I go about this?

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

(PS. I assume that Prototype's class system has something built in for this. However I would rather not rewrite a bunch of my code to use that class system)

推荐答案

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

The problem is that your A constructor function is only run once for all B instances, and so this.y is a reference to just one array. Any reference to it from B will be resolved via the prototype chain to the single, central A reference, which only has one y. This is a very useful feature, just not for what you're trying to do here.

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

The answer is to separate construction from initialization; the constructor sets up central resources and the initializer initializes an instance. This is how the issue is handled by most of the "class" implementations I've seen for JavaScript. For that to work, you have to provide a means for each level in the hierarchy to call the previous level's initializer (which is useful for other methods as well) -- e.g., supercalls.

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

Supercalls are why you're probably better off using something like Prototype for this: They're hard to do well, and it's very easy to fall into the "grandchild" problem -- a solution that seems to work, but ends up only working with a Parent<-Child structure, not a Parent<-Child<-GrandChild structure.

但是,如果你'我将继续做你自己的继承机制,这篇关于超级电话的帖子来自我可怜的博客可能会有所帮助,因为我会深入研究其中的一些问题。它需要Prototype的继承机制的简化版本,解构它一点,并讨论一种做超级调用的方法,这种方式与Prototype目前的超级调用没有一些问题。这可能会帮助您在自己的机制中完成它们。

However, if you're going to do your own inheritance mechanism, this post on supercalls from my pathetically-anemic blog may be helpful as I go into some of those issues in depth. It takes a simplified version of Prototype's inheritance mechanism, deconstructs it a bit, and talks about a way to do supercalls that doesn't have some issues I have with Prototype's current supercalls. That may help you with doing them in your own mechanism.

这篇关于Javascript继承 - 在构造函数中声明的对象是在实例之间共享的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆