是否可以通过javascript原型分配每个实例成员?

时间:2013-02-23 16:18:44

标签: javascript prototype

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

以下是我正在尝试做的一个浓缩示例:

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是否提供了一种方法来实现这一点,而无需进行实例复制?

2 个答案:

答案 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