JavaScript OOP:对象改变原型(对于使用相同原型的所有其他对象)

时间:2014-01-04 01:33:56

标签: javascript oop prototype javascript-objects

function NamedRoundedBlock(){
    var name = this.makeFeild("name");
    name.className = "Block NamedRound name";
    this.element.className = "Block NamedRound root";
    this.element.appendChild(name);
}
NamedRoundedBlock.prototype = new Block();
NamedRoundedBlock.prototype.constructor = NamedRoundedBlock;

有代码,有人知道我做错了吗?

我的问题是,如果我创建两个NamedRoundedBlock对象并更改一个this.element属性(通过更改属性或其他内容),另一个也将更改。

此外,还有一些额外的细节,this.makeFeildthis.element都在Block

中设置

2 个答案:

答案 0 :(得分:1)

原型是共享属性的地方。

考虑:

var protoCircle - {x: 0, y: 0, radius: 1}

这意味着每个圈子都将这些属性设为默认值。所以如果我用这个原型制作圈子:

var c1 = Object.create(protoCircle);
c1.x = 3;

var c2 = Object.create(protoCircle);
c2.y = 5;

然后圈c1位于(3,0),半径为1,c2位于(0,5),半径为1.这是因为c1只有一个自己的属性x)和两个继承的属性yradius),它从原型中获取。如果我更改protoCircle.radius,则两个圈子都会看到该更改。这就是JavaScript的设计方式!此设计允许一大堆对象共享默认值,因此您不必将其存储在每个对象中。您只需将属性设置为每个对象内的每个对象,并在原型中共享默认属性。在上面的例子中,如果99%的圆的半径为1,那么我们就不必在各个圆圈中存储半径。

在您的情况下,您将一个名为element的属性放入原型中。共享该原型的所有对象将具有element的相同值。所以,如果你说

x.element.className = 'something'

然后这有效地使y.element.className成为something,假设yx共享相同的原型。

如果您希望每个命名的舍入块都有不同的元素,那么您需要这样做:

function NamedRoundedBlock(){
    ...
    this.element = {}
    this.element.className = "Block NamedRound root";
    this.element.appendChild(name);
}

答案 1 :(得分:0)

查看Traditional OOP Inheritance in JavaScript

上述博文可能有助于回答您的一些问题。

它详细阐述了为对象定义一个新的构造函数,它从父代“继承”。这是你的一个问题吗?以此为例:

NamedRoundedBlock.prototype = Object.create(
    Block.prototype,
        {
            "constructor": { 
                configurable: true,
                enumerable: false,
                writable: true,
                value: 'NamedRoundedBlock'
            }
        }
);

上面创建了一个基于 Block 原型的对象,但它定义了自己的构造函数,并将其设置为不可枚举

另外,第一行是否应该是这样的?:

function NamedRoundedBlock() {
    this.name = this.makeFeild("name");
    //etc.

此外,独立于问题,我会小心拼写“Feild”(拼写为“Field”),因为拼写问题有时会在代码中导致难以发现的错误。