在学习这篇博文前,请先移步我的另外一篇博文:JS 一张图理解prototype、proto和constructor的关系(点击可进入),先弄清楚prototype\proto\constructor直接的关系。
本博文主要讲解下面的方案:
- Child.prototype = new Parent(); Child类的prototype指向Parent的实例
- Child.prototype = Parent.prototype; Child类的prototype指向Parent类的prototype
方案1:Child.prototype = new Parent();
// 方案1:Child.prototype = new Parent();
function Animal() {
this.type = '动物';
}
Animal.prototype.getType = function(){
console.log(this.type);
}
function Cat(){
this.vary = '猫';
}
Cat.prototype.getVary = function(){
console.log(this.vary);
}
Cat.prototype = new Animal();
var cat = new Cat();
cat.getType(); // 动物
// cat.getVary() // 报错:cat.getVary is not a function [原因:Cat.prototype = new Animal()的操作覆盖了原型链]
console.log(Cat.prototype.constructor); // Animal
console.log(cat.constructor); // Animal 这个constructor实质调用的是Animal.prototype.constructor
// 修改Cat类的constructor为Cat
Cat.prototype.constructor = Cat;
console.log(Cat.prototype.constructor); // Cat
console.log(cat.constructor); // Cat
// 修改Cat类prototype上的getType方法,看是否影响Animal类的getType方法
Cat.prototype.getType = function(){
console.log('我是猫科类');
}
var animal = new Animal();
animal.getType(); // 动物
总结:
- Cat类的prototype指向Animal的实例,将覆盖Cat类的prototype上的所有属性,所以Cat类的prototype属性应该在覆盖后定义;
- Cat类的prototype指向Animal的实例,Cat类的constructor指向Animal;Cat类的constructor必须重新指定为Cat;
- Cat类的prototype指向Animal的实例,修改Cat原型链上的、与Animal同名方法,不会影响Animal类
方案2:Child.prototype = Parent.prototype;
// 方案2:Child.prototype = Parent.prototype; function Animal() { this.type = '动物'; } Animal.prototype.getType = function(){ console.log(this.type); } function Cat(){ this.vary = '猫'; } Cat.prototype.getVary = function(){ console.log(this.vary); } // Cat.prototype = new Animal(); Cat.prototype = Animal.prototype; var cat = new Cat(); cat.getType(); // undefined // cat.getVary() // 报错:cat.getVary is not a function [原因:Cat.prototype = new Animal()的操作覆盖了原型链] console.log(Cat.prototype.constructor); // Animal console.log(cat.constructor); // Animal 这个constructor实质调用的是Animal.prototype.constructor // 修改Cat类的constructor为Cat Cat.prototype.constructor = Cat; console.log(Cat.prototype.constructor); // Cat console.log(cat.constructor); // Cat // 修改Cat类prototype上的getType方法,看是否影响Animal类的getType方法 Cat.prototype.getType = function(){ console.log('我是猫科类'); } var animal = new Animal(); animal.getType(); // 我是猫科类
总结:
- Child类的prototype指向Parent类的prototype,将覆盖Cat类的prototype上的所有属性,所以Cat类的prototype属性应该在覆盖后定义;
- Child类的prototype指向Parent类的prototype,Cat类的constructor指向Animal;Cat类的constructor必须重新指定为Cat;
- Child类的prototype指向Parent类的prototype,修改Cat原型链上的、与Animal同名方法,会影响Animal类
- 所以,这样的继承方案是及其不合理的