问题描述
|
我正在尝试创建一个可以创建多个实例的主对象,每个实例都继承这些子对象(具有唯一/隔离的属性)。但是,当我执行此操作时,所有创建的对象的对象属性(更改后)都会更改。我可能没有正确解释,但是示例应该很清楚。
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,这样我就有了彼此独立的隔离对象。
有任何想法吗?我只是缺少明显的东西吗?将不胜感激!
解决方法
\“ foo \”属性位于原型对象上,并且只有其中一个。通过任何实例进行设置时,都将影响同一共享属性。
您可以在构造函数中添加实例属性:
function Main() {
this.instanceProperty = 1;
}
然后,将按实例进行。
原型不是“主模板”或类似的东西;这是一个真实的对象。它不会复制到实例上。相反,运行时知道它在那儿,并且当引用某个实例上实际上不存在的实例上的属性时,它就会知道在原型链中查找并在其中查找属性。
, 其他答案或多或少是正确的,但是它们所缺少的是
Main.prototype.foo = {
bar: 1
};
和
Main.prototype.bar = 1;
在这两种情况下,实例化一个新的“ 4”将创建一个新实例,该实例在其原型链中具有属性“ 5”或“ 6”。在这两种情况下,都可以在不影响其他实例的情况下重新定义实例级属性:
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}
的引用,该对象在所有实例之间共享。因此,当您设置“ 11”时,您正在更改的是公共对象,而不是实例变量。实例变量是参考“ѭ12”。
您不必在构造函数中初始化instance属性。标准方法是直接在原型上设置bar
,即Main.prototype.bar = 1
,这将为您提供初始化为1
的独立实例变量。但是,如果根据每个实例需要更复杂的数据结构(对象,数组或另一个类的实例),则不能在原型上将其创建为属性,因为将为每个实例提供对公共对象的引用-因此在构造函数内部是可行的方法:
function Main() {
// instance-level object
this.foo = {
bar: 1
};
}
, 由于您要在原型上进行编辑,因此它将影响每个对象。
但是,您可以执行以下操作:
A.x = 2;
B.x = 3;
然后,您将得到不同的结果。
或者,您可以具有以下内容:
Main = function(val){
this.x = val;
}
A = new Main(2);
B = new Main(3);