1

当我将一个结构与一个函数的原型相关联,然后用该函数实例化多个对象时,它们都共享同一个结构实例。我希望每个对象都有自己的结构实例,而不必在实例化对象时显式创建新实例;那可能吗?

这是我正在尝试做的一个简明示例:

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 是否提供了一种无需实例化复制的方法?

4

2 回答 2

2

我认为这里对原型的用途存在误解。它用于新类的每个实例的共享成员。这些通常是函数实现,而不是属性值。

您的第二个示例有效的原因以及 Bergie 的回答有效的原因是您都首先定义了prototype.model,然后稍后在构造函数(?)中覆盖它。

在有问题的第二个示例中发生以下情况:

第一constructor.prototype.model = instanceMembers.model;

2nd - 从defineClass返回构造函数后,它被执行 -this.model = $.extend(true, {}, this.model);它覆盖来自原型的模型。

所以你不必将属性的实例化放在原型中,而是放在构造函数中。

在此处查看有关 javascript 原型的详细答案。

于 2013-02-23T17:58:51.240 回答
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
于 2013-02-23T17:35:50.400 回答