为什么重写原型不成功?

时间:2013-01-21 08:31:12

标签: javascript prototype

function DivElement(){
    this.ctor.apply(this,arguments);
}

DivElement.prototype = {
    obj:{
        name:'',
        src:''
    },
    objName:'',
    objSrc:'',

    ctor:function(){
        this.obj.name = arguments[0];
        this.obj.src = arguments[1];
        this.objName = arguments[0];
        this.objSrc = arguments[1];
    }
}

var d1 = new DivElement('a','a.jpg');
var d2 = new DivElement('b','b.jpg');

console.log(d1.obj.src);    //b.jpg
console.log(d2.obj.src);    //b.jpg
console.log(d1.objSrc);     //a.jpg
console.log(d2.objSrc);     //b.jpg

问题是为什么d1.obj.src不是'a.jpg'?

如果我像这样重写函数ctor:

ctor:function(){
    this.obj = {name:arguments[0],src:arguments[1]};
    this.objName = arguments[0];
    this.objSrc = arguments[1];
}

它运作正常!

谁能告诉我那边发生了什么......

2 个答案:

答案 0 :(得分:1)

您遇到的问题是DivElement的实例共享相同的对象obj,除非您没有明确地将其指定为您实例的属性。

因此,实际发生的是这一行this.obj.src = arguments[1];

您正在覆盖被所有实例遮蔽的对象src的属性obj

所以,一旦你第二次执行ctor,你就会覆盖d1的属性src,其值为a,而d2属于this.objSrc = arguments[1]; 1}}用。初始化。

this.obj = {name:arguments[0],src:arguments[1]};是它自己的实例的自有属性,因此每个实例都有自己的副本,并且在第二次执行时不会被覆盖。

同样适用于obj,因为您明确地将对象{{1}}分配给每个实例。

答案 1 :(得分:0)

原型中的项目不会为每个新对象进行深度复制。因此,当您尝试使用原型中的obj.name时,所有对象只有obj的一个副本。因此,您的第二个对象将从第一个对象覆盖obj,并且需要混淆。原型最适用于函数或常量,而不适用于对象和数组。

最好将obj添加到构造函数中的实例数据中,这样每个实例都会有一个新的,如下所示:

function DivElement(){
    this.ctor.apply(this,arguments);
}

DivElement.prototype = {
    ctor:function(){
        this.obj = {};
        this.obj.name = arguments[0];
        this.obj.src = arguments[1];
        this.objName = arguments[0];
        this.objSrc = arguments[1];
    }
}

var d1 = new DivElement('a','a.jpg');
var d2 = new DivElement('b','b.jpg');

console.log(d1.obj.src);    //b.jpg
console.log(d2.obj.src);    //b.jpg
console.log(d1.objSrc);     //a.jpg
console.log(d2.objSrc);     //b.jpg