我正在尝试使用prototype:
将一个构造函数扩展为另一个构造函数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
。也许有人可以指出我做错了什么,或者可能是其他解决方案。感谢。
答案 0 :(得分:4)
JavaScript通过链接对象实现继承。 objA
有一个原型属性test
,它是objB
的一个实例。这与objA
objA.prototype.test = new objB();
现在,在objA
的构造函数中,它会修改objA.prototype.test
的所有objA
实例共享的objA
。这意味着name
的所有实例都将具有值“D”,因为上次迭代使共享属性保持为“D”。
如果要为每个实例you need to attach it to the instance保留唯一的var objA = function (name) {
this.name = name;
}
属性,而不是共享父级。
name
现在,您似乎注意到两个实例和共享父级都有name
。好吧,JS首先从实例中读取。如果它看到属性console.log
,则从那里获取它的值。如果没有,它从共享父节点读取,默认为“test”。
It can be seen here,我在那里做了一个小{{1}}。您可以看到该值具有2个名称属性,一个在实例上,在父项上,但它首先读取实例的值。
答案 1 :(得分:1)
Prototype就像静态函数一样,所有实例共享一个,所以objA的所有实例共享一个指向同一个objB实例的test属性
通常为属性分配新值会为实例属性设置该值:Prototypical inheritance - writing up
在这种情况下,您为原型的属性而不是原型赋值,因此它将为所有实例分配一个新值。
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);
答案 2 :(得分:0)
你的问题是setTimeout。你正在创建一个事件处理程序,它运行在最后的已知信息上,在这种情况下,当函数传递给'D'时。没有setTimeout,它会给出正确的值。
你可能想要在setTimeout中包装新的objA(a [i])。
window.setTimeout(function(a){
new objA(a[i]);
}(a), 1);
因为关闭。
答案 3 :(得分:-1)
您应该在原型
中创建“createTest”函数而不是“test”对象