OOP Javascript-在类中隔离对象

OOP Javascript-在类中隔离对象,javascript,prototype-programming,Javascript,Prototype Programming,我试图拥有一个可以创建多个实例的主对象,每个实例都继承子对象(具有唯一/隔离的属性)。但是,当我执行此操作时,对象的属性(在更改后)正在为所有创建的对象更改。我可能没有正确地解释这一点,但这个例子应该非常清楚 Main = function(){}; // Extending the main class with new object. Doing it this way so I can have these in // separate files. Main.prototype.foo

我试图拥有一个可以创建多个实例的主对象,每个实例都继承子对象(具有唯一/隔离的属性)。但是,当我执行此操作时,对象的属性(在更改后)正在为所有创建的对象更改。我可能没有正确地解释这一点,但这个例子应该非常清楚

Main = function(){};

// Extending the main class with new object. Doing it this way so I can have these in
// separate files.
Main.prototype.foo = {
    bar: 1
}

// First instance of Main().
var A = new Main();

// Second instance of Main().
var B = new Main();

// Set the bar property to different values for each Main() object.
A.foo.bar = 2;
B.foo.bar = 3;

// Both A.foo.bar and B.foo.bar return 3.
alert(A.foo.bar);
alert(B.foo.bar);
我想让A.foo.bar返回2,B.foo.bar返回3,这样我就有了相互独立的独立对象

有什么想法吗?我是不是错过了一些显而易见的东西?非常感谢

prototype对象上有“foo”属性,其中只有一个。当您通过任何实例进行设置时,都会影响相同的共享属性

您可以在构造函数中添加实例属性:

  function Main() {
    this.instanceProperty = 1;
  }
那就是每个实例


原型不是“主模板”或类似的东西;这是一个真实的物体。它不会复制到实例上。相反,运行时知道它在那里,当引用实例上不存在的属性时,它知道在原型链上查找属性。

由于您在原型上编辑某些内容,它将影响每个对象

但是,您可以执行以下操作:

A.x = 2;
B.x = 3;
然后你会得到不同的结果

或者,你可以有这样的东西:

Main = function(val){
  this.x = val;
}

A = new Main(2);
B = new Main(3);

其他答案或多或少都是正确的,但他们缺少的是两者之间的区别

Main.prototype.foo = {
    bar: 1
};

在这两种情况下,实例化一个新的
Main
将在其原型链中创建一个新实例,其中包含一个属性
foo
bar
。在这两种情况下,可以在不影响其他实例的情况下重新定义实例级属性:

function Main() {};
Main.prototype.foo = {
    bar: 1
};
Main.prototype.bar = 1;

a = new Main();
b = new Main();

a.foo = { bar: 2 };
console.log(a.foo.bar, b.foo.bar); // 2 1

a.bar = 2;
console.log(a.bar, b.bar); // 2 1
但是,当您实例化一个新的
Main
时,实例变量
foo
是对单个对象
{bar:1}
的引用,该对象在所有实例之间共享。因此,当您设置
a.foo.bar
时,您正在更改公共对象,而不是实例变量;实例变量是引用
a.foo

您不必在构造函数中初始化实例属性。标准方法是直接在原型上设置
bar
,即
Main.prototype.bar=1
,这将为您提供初始化为
1
的独立实例变量。但是,如果您需要基于每个实例的更复杂的数据结构(对象、数组或另一个类的实例),则不能将其创建为原型上的属性,因为您将为每个实例提供一个对公共对象的引用-因此在构造函数内部是一种方法:

function Main() {
    // instance-level object
    this.foo = {
        bar: 1
    };
}

为什么要设置“foo”两次?这仅仅是一个转录错误吗?请看这篇优秀的文章,以清楚地理解原型是如何工作的:我认为“实例变量foo是对单个对象的引用”这句话对于理解在foo中操纵属性的行为很重要。
function Main() {
    // instance-level object
    this.foo = {
        bar: 1
    };
}