1

我正在尝试使用原型扩展一个构造函数:

var objA = function(name){

    var obj = this; 

    this.test.name = name;

    window.setTimeout(function(){
        console.log(obj.test.name)
    }, 1)

}

var objB = function(name){

    this.name = 'test'


}

objA.prototype.test = new objB();

var a = ['A', 'B', 'C', 'D']

for(var i = 0; i < a.length; i++){
   new objA(a[i])
}

这种方法适用于一个对象,但如果(如本例中)我想创建多个,似乎最后一个条目('D')会覆盖以前的条目,因为在所有 4 种情况下obj.test.name都会返回D。也许有人可以指出我做错了什么,或者这种情况下的其他解决方案。谢谢。

4

4 回答 4

4

JavaScript 通过链接对象来实现继承。objA有一个原型属性test,它是objB. 这是共享给所有实例的objA

objA.prototype.test = new objB();

现在在您的构造函数中objA,它会修改objA.prototype.test在所有实例之间共享的objA. 这意味着所有实例都objA将具有值“D”,因为最后一次迭代使共享属性保持“D”。

如果您想name为每个实例保留一个唯一属性,则需要将其附加到实例,而不是共享父级。

var objA = function (name) {
  this.name = name;
}

现在,您似乎注意到name在两个实例和共享父级上都有。好吧,JS首先从实例中读取。如果它看到一个属性name,它会从那里获取它的价值。如果不是,它从共享父级读取,默认为“测试”。

可以在这里看到,我对它们做了一个未成年console.log人。您可以看到该值有 2 个名称属性,一个在实例上,一个在父级上,但它首先读取实例的值。

于 2013-05-10T08:48:32.393 回答
1

原型就像静态函数,所有实例共享一个,所以 objA 的所有实例共享一个指向同一个 objB 实例的测试属性

通常为属性分配新值会为实例属性设置该值:原型继承 - 编写

在这种情况下,您将值分配给原型的属性而不是原型,因此它将为所有实例分配一个新值。

var objA = function(name){
    var obj = this; 
    this.test.name = name;
    console.log("this.name.is:",this.test.name);
}

var objB = function(name){
    this.name = 'test'
}
objA.prototype.test = new objB();
objA.prototype.arr=[];

var a = ['A', 'B', 'C', 'D']
var arr=[];
for(var i = 0; i < a.length; i++){
   arr.push(new objA(a[i]))
}
console.log(arr[0].test.name)
arr[0].arr.push("pushed in 0");
console.log(arr[1].arr);
arr[0].arr=["assigned in 0"];
console.log(arr[1].arr);
arr[0].test.name="assigned in 0";
console.log(arr[1].test.name);
于 2013-05-10T09:00:31.490 回答
0

你的问题是setTimeout。您正在创建一个在最后一个已知信息上运行的事件处理程序,在这种情况下,当函数传递“D”时。如果没有 setTimeout,它会给出正确的值。

您可能希望将 new objA(a[i]) 包装在 setTimeout 中。

window.setTimeout(function(a){   
 new objA(a[i]);
}(a), 1);

因为关门。

于 2013-05-10T08:45:40.090 回答
-1

您应该在原型中创建“createTest”函数而不是“test”对象

于 2013-05-10T08:54:28.060 回答