2013-05-10 53 views
0

我试图用另一种延长一个构造函数,用原型:的JavaScript - 将两个构造

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。也许有人可能会指出我做错了什么,或者可能是其他解决方案。谢谢。

回答

3

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

objA.prototype.test = new objB(); 

现在在构造函数所有实例objA,它会修改其跨的objA所有实例共享objA.prototype.test。这意味着objA的所有实例将具有值“D”,因为上次迭代使共享属性保持为“D”。

如果您想为每个实例保留一个唯一的name属性,而不是共享的父级,则为you need to attach it to the instance

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

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

It can be seen here,我在那里做了一个小console.log。你可以看到这个值在父对象上有两个名字属性,一个在实例上,但它首先读取实例的值。

+0

它更容易混淆,直接重新分配实例的原型时,它只会影响实例instanceOfA.test = [1,2,3]不会影响其他A实例的测试属性。但是如果A会有像A.prototype.anArray = []然后instanceOfA.anArray.push(“22”)的原型的数组将影响其他实例。因此,直接给原型分配一个新的值**。test = **不会影响其他实例,而是直接分配原型的属性**。test.name = **会影响其他实例。 – HMR 2013-05-10 09:06:20

+1

您可以通过在objA主体中进行下列操作来继承其他函数:objB.call(this)将objB函数体中定义的所有变量作为** this.something = ** objA的一部分它不是与原型设计相同,原型更像静态函数/属性,其中所有实例共享原型并设置objA.prototype = new objB(),然后再执行objB.prototype.somethingNew = ...然后objA和objB的所有实例都将具有somethingNew – HMR 2013-05-10 09:15:22

+0

@HMR数组的情况下,只有[该实例没有同名的属性](http://jsfiddle.net/mpxjQ/2/)。否则,它只会影响实例。 – Joseph 2013-05-10 09:15:50

0

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

您可能想要将新的objA(a [i])包装在setTimeout中。

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

由于关闭。

+0

我看,我说的setTimeout只是模拟对象中活动的条件,因为在真正的解决办法,我想每个objA实例添加哈希改变事件,但我有同样的问题,所有的数据传入该事件处理程序等于最后一个对象(D)。有没有解决的办法? – 2013-05-10 08:52:50

+0

看看Joseph发布的答案。 – 2013-05-10 08:53:25

-1

你应该做一个“的CreateTest”功能,而不是在PROTOTYP

1

原型就像是静态函数“测试”对象,所有实例共享一个如此objA的所有实例共享指向同一个试验性质的objB

实例通常分配给一个属性的新值将设置为实例的属性,值:Prototypical inheritance - writing up

在这种情况下,你assing值原型的属性,而不是原型所以它会为所有实例分配一个新值。

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);