原型继承和原型对象,为什么不能在这个范围内使用?

时间:2016-12-31 07:10:07

标签: javascript prototypal-inheritance

我做了一个快速搜索,但似乎无法找到这个问题的答案,只是指在继承时复制函数原型。 为什么不向构造函数prototype obj添加属性,而不是使用this关键字。我确定有理由不这样做,但我试图更好地理解javascript的细微差别。例如,在正常的原型继承中,你会"这个"。

 function Dog(name,age,breed){
         this.name=name;
         this.age=age;
         this.breed=breed;
 }
 Dog.prototype.bark=function(){console.log("bark bark bark");}

 let spike=new Dog("Spike",6,"lab");
 let rover=new Dog("Rover",8,"poodle");


 //^with the constructor function, no instance has the bark function but
 //but refers to the same function on the constructor prototype obj, so the 
 //same function isn't being duplicated. However new keyword changes the 
 //context of this to refer to the obj so these properties are duplicated
 //on every instance.

 //I'm curious as to the reason why new doesn't change this to refer to the 
 //prototype obj for example and then have the instance refers its
 //constructor's prototype like with the bark function?

//for example why isn't this a common pattern and what are the reasons I 
//should use it.


function Dog(name,age,breed){
       Dog.prototype.name=name;
       Dog.prototype.age=age;
       Dog.prototype.breed=breed;
}

let spike=new Dog("Spike",6,"lab");
let rover=new Dog("rover",8,"poodle");


//I feel like the above code would be more DRY, I'm sure there is a reason
// this isn't common and I'm curious as to why

1 个答案:

答案 0 :(得分:3)

当您在原型上有properties时,每次实例化Class时都会使用新值覆盖属性,即在您的示例中,从以下两个语句中删除:

let spike=new Dog("Spike",6,"lab");

let rover=new Dog("rover",8,"poodle");

此处,根据您的预期,spike.name应为Spikerover.name应为rover,但如果执行此代码并进行检查,则两者均为{ {1}}。

创建新实例rover时,spike的属性会覆盖rover的属性。 每次,您创建一个新实例,属性被覆盖,原因是 附加到原型的 rovermethods仅创建一次,并且每次创建新实例时都会继承到其子类

我们创建构造函数及其新实例的原因是因为我们为propertiesSpike等每个实例都有不同的属性。在方法的情况下,方法对于构造函数是通用的,可以为每次创建新实例时不需要创建的所有实例重用这些方法,因此,我们将它们附加到rover而不是使用{来定义它构造函数中的{1}}关键字。