JS 详解prototype与继承

在学习这篇博文前,请先移步我的另外一篇博文: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类
  • 所以,这样的继承方案是及其不合理的


猜你喜欢

转载自www.cnblogs.com/minigrasshopper/p/9150470.html