javascript-组合两个构造函数

javascript-组合两个构造函数,javascript,object,prototype,Javascript,Object,Prototype,我正在尝试使用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' }

我正在尝试使用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。也许有人可以指出我做错了什么,或者针对这种情况的其他解决方案。谢谢。

您的问题是设置超时。在本例中,当传递函数“D”时,您正在创建一个基于最后已知信息运行的事件处理程序。如果没有setTimeout,它将提供正确的值

您可能希望将新的objAa[i]包装在setTimeout中

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

因为闭包。

您的问题是设置超时。在本例中,当传递函数“D”时,您正在创建一个基于最后已知信息运行的事件处理程序。如果没有setTimeout,它将提供正确的值

您可能希望将新的objAa[i]包装在setTimeout中

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

因为闭包。

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

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

如果要为每个实例而不是共享父实例保留唯一的name属性

var objA = function (name) {
  this.name = name;
}
现在,您似乎注意到实例和共享父级上都有名称。JS首先读取实例。如果它看到一个属性名,它将从中获取它的值。如果不是,则从共享父级读取,默认为“test”


,我在那里做了一个小控制台。登录它们。您可以看到该值有两个名称属性,一个在实例上,一个在父对象上,但它首先读取实例的值。

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

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

如果要为每个实例而不是共享父实例保留唯一的name属性

var objA = function (name) {
  this.name = name;
}
现在,您似乎注意到实例和共享父级上都有名称。JS首先读取实例。如果它看到一个属性名,它将从中获取它的值。如果不是,则从共享父级读取,默认为“test”


,我在那里做了一个小控制台。登录它们。您可以看到该值有两个名称属性,一个在实例上,一个在父对象上,但它首先读取实例的值。

您应该在原型中创建createTest函数而不是测试对象。

您应该在原型中创建createTest函数而不是测试对象。

原型类似于静态函数,所有实例共享一个,因此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);

原型类似于静态函数,所有实例共享一个,因此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);

我明白了,我添加setTimeout只是为了模拟对象内事件的条件,因为在实际解决方案中,我想在每个objA实例上添加hash change事件,但我遇到了相同的问题,即传入该事件处理程序的所有数据都等于最后一个对象D。有办法解决这个问题吗?看看Joseph发布的答案。我明白了,我添加setTimeout只是为了模拟对象内事件的条件,因为在实际解决方案中,我想在每个objA实例上添加hash change事件,但我遇到了相同的问题,即传入该事件处理程序的所有数据都等于最后一个对象D。有办法解决这个问题吗?看看Joseph发布的答案。这会让人更加困惑,当直接重新分配实例的原型时,它只会影响实例instanceOfA。test=[1,2,3]不会影响a的其他实例的test属性。但是如果a会为a.prototype.anArray=[]然后instanceOfA.anArray.push22将影响其他实例。因此,直接为prototype.test=分配一个新值不会影响其他实例,而是直接影响assi
gning prototype.test.name=的属性将影响其他实例。您可以通过在objA主体中包含以下内容从其他函数继承它:objB.callthis,它将接受objB函数主体中定义的所有变量。something=objA的一部分它与原型不同,因为原型更像是静态的函数/属性,其中所有实例共享原型并设置objA.prototype=new objB,然后执行objB.prototype.somethingNew=。。。那么objA和objB的所有实例都将具有somethingNew@HMR数组的情况仅当。否则,它只会影响实例。两者上的名称都是错误的,应该只有objA的名称,但这不会有太大变化。我想我现在明白了,基本上objB将始终在objA的所有实例中共享,因为它不能保存任何唯一的数据,因为它将被其他实例覆盖。非常感谢。@BenasR。数据只能由实例携带。通常不鼓励共享数据,除非你知道自己在做什么。通常是共享的函数。这会让人更加困惑,当直接重新分配实例的原型时,它只会影响实例instanceOfA。test=[1,2,3]不会影响a的其他实例的test属性。但是如果a会为a.prototype.anArray=[]然后instanceOfA.anArray.push22将影响其他实例。因此,直接为prototype.test=分配一个新值不会影响其他实例,但直接为prototype.test.name=分配一个属性会影响其他实例。您可以通过在objA body中包含以下内容从其他函数继承它:objB.callthis,它将把objB函数体中定义的所有变量作为this.something=objA的一部分与原型设计不同,因为原型设计更像是静态函数/属性,其中所有实例共享原型并设置objA.prototype=new objB,然后再执行objB.prototype.somethingNew=。。。那么objA和objB的所有实例都将具有somethingNew@HMR数组的情况仅当。否则,它只会影响实例。两者上的名称都是错误的,应该只有objA的名称,但这不会有太大变化。我想我现在明白了,基本上objB将始终在objA的所有实例中共享,因为它不能保存任何唯一的数据,因为它将被其他实例覆盖。非常感谢。@BenasR。数据只能由实例携带。通常不鼓励共享数据,除非你知道自己在做什么。这些功能通常是共享的。