当我将结构与函数的原型相关联,然后使用该函数实例化多个对象时,它们都共享相同的结构实例。我希望每个对象拥有它自己的结构实例,而不必在实例化对象时显式创建新实例;那可能吗?
以下是我正在尝试做的一个浓缩示例:
function defineClass(constructor, instanceMembers) {
constructor.prototype.model = instanceMembers.model;
return constructor;
}
var visualObject = defineClass(function () { }, {
model: {
setPosition: function (x, y) {
this.x = x;
this.y = y;
}
}
});
var testA = new visualObject();
var testB = new visualObject();
testA.model.setPosition(10, 10);
console.log(testB.model.x); // outputs "1", but want it to be undefined
这不起作用,因为testA.model和testB.model都引用同一个实体。
如果我在构造时克隆结构,那么它可以工作,但我真的希望避免克隆操作。这段代码有效,但让我受伤:
function defineClass(instanceMembers) {
var constructor = function () {
// Create a copy of the model member in this object instance
this.model = $.extend(true, {}, this.model);
};
constructor.prototype.model = instanceMembers.model;
return constructor;
}
var visualObject = defineClass({
model: {
setPosition: function (x, y) {
this.x = x;
this.y = y;
}
}
});
var testA = new visualObject();
var testB = new visualObject();
testA.model.setPosition(10, 10);
console.log(testB.model.x); // is undefined, as expected
javascript是否提供了一种方法来实现这一点,而无需进行实例复制?
答案 0 :(得分:2)
我认为这里存在误解原型的用途。它用于每个新类实例的共享成员。这些通常是函数实现,而不是属性值。
为什么你的第二个例子工作以及为什么Bergie的答案工作的原因是你们首先定义prototype.model然后在构造函数(?)中覆盖它。
发生以下问题的第二个例子:
第一constructor.prototype.model = instanceMembers.model;
2nd - 从defineClass返回构造函数后,它被执行 - this.model = $.extend(true, {}, this.model);
并覆盖来自原型的模型。
所以你不必在原型中放置属性的实例化,而是在构造函数中。
查看有关javascript原型here的详细答案。
答案 1 :(得分:1)
javascript是否提供了一种方法来实现这一点,而无需进行实例复制?
是。您不希望克隆/复制实例化,而是希望模型具有共同的原型对象:
function defineClass(constructor, prototypeMembers) {
$.extend(constructor.prototype, prototypeMembers);
return constructor;
}
var ModelObject = defineClass(function() {}, {
setPosition: function (x, y) {
this.x = x;
this.y = y;
}
});
var VisualObject = defineClass(function() {
this.model = new ModelObject;
});
var testA = new VisualObject;
var testB = new VisualObject;
testA.model.setPosition(10, 10);
console.assert(testA.model !== testB.model);
console.log(testB.model.x); // undefined