继承学习总结

继承

1.原型链继承:

让子类的原型对象指向父类的实例,当子类的实例找不到对应的方法时,就按原型链往上找。

function Parent(){
    this.name = ["原型链继承"];
}
// 原型上挂载方法
Parent.prototype.getName = function(){
    console.log(this.name);
}
function Chind(){

}
// 原型链继承
Chind.prototype = new Parent();
//原型链继承会改变constructor指向,要设置重新指回
Chind.prototype.constructor = Chind;

let myChild1 = new Chind();
let myChild2 = new Chind();
myChild1.name[0] = "咕咕咕";
console.log(myChild1.name); //["咕咕咕"]
myChild2.getName();         //["咕咕咕"]

弊端:

  1. 原型都指向同一个Parent实例,当有两个子类实例化对象时,其中一个修改了Parent的内容,那么另一个实例也会受到影响。
  2. 原型链继承会改变constructor指向,要设置重新指回
  3. 无法对父类进行super传参。

2.构造函数继承:

在子类的构造函数中,去执行父类的构造函数,并绑定子类的this

// 构造方法继承
    function Parent(name){
        this.name =name;
    }
    // 原型上挂载方法
    Parent.prototype.getName = function(){
        console.log(this.name);
    }
    function Chind(){
        Parent.call(this,"fct");
    }
    let myChild1 = new Chind();
    let myChild2 = new Chind();
    myChild1.name = "咕咕咕";
    console.log(myChild1.name); //"咕咕咕"
    console.log(myChild2.name); // fct
    myChild2.getName();         //报错,构造方法继承不能继承父类原型上的属性和方法

弊端:

构造方法继承解决了子类实例都指向同一个父类实例,但构造方法继承不能继承父类原型上的属性和方法

3.组合继承

组合继承 = 构造函数继承 + 原型链继承

// ----组合继承-----
function Parent(name){
    this.name = name;
}
Parent.prototype.getName = function (){
    console.log(this.name);
}
function Child(){
    Parent.call(this,"小桃子");
}
Child.prototype = new Parent();
Child.prototype.constructor = Child;

let myChild1 = new Child();
let myChild2 = new Child();
myChild1.name = "咕咕咕";
console.log(myChild1.name); // 咕咕咕
console.log(myChild2.name); // 小桃子
myChild2.getName();     // 小桃子

缺点:每生成一个子类实例就得new 一个父类实例和执行一次call函数。导致父类构造函数始终会被调用两次。

4. 寄生式继承

function Parent(name){
    this.name = [name];
}
Parent.prototype.getName = function (){
    console.log(this.name);
}
function Child(){
    Parent.call(this,"水云身");
}
Child.prototype = Parent.prototype;
Child.prototype.constructor = Child;

Child.prototype.print = function (){
    console.log("我是child");
}

let myChild1 = new Child();
let myChild2 = new Child();
myChild1.name[0] = "咕咕咕";
console.log(myChild1.name); // 咕咕咕
console.log(myChild2.name); // 水云身
myChild2.getName();     // 水云身

myChild1.print();   //我是child
let myParent = new Parent();
myParent.print();   //我是child

缺点:避免了父类构造函数始终被调用两次,但子类对原型上的修改会影响(污染)父类的原型。

5.寄生式组合继承

基本思路:不通过调用父类构造函数给子类原型赋值,而是取得父类原型的一个副本。

function Parent(name){
    this.name = name;
}
Parent.prototype.getName = function (){
    console.log(this.name);
}
function Child(){
    Parent.call(this,"卿云");
}
//子类原型 = 父类原型的一个副本
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

Child.prototype.print = function (){
    console.log("我是child");
}

let myChild1 = new Child();
let myChild2 = new Child();
let myParent = new Parent();
myChild1.name = "咕咕咕";
console.log(myChild1.name); // 咕咕咕
console.log(myChild2.name); // 卿云
myChild2.getName();     // 卿云
myParent.getName();     //undefined

myChild1.print();   //我是child
myParent.print();   //报错:myParent.print is not a function

子类原型上的修改不会影响到父类原型。寄生式组合继承算是继承的最佳模式

posted @ 2021-09-03 15:12  青柠i  阅读(54)  评论(0编辑  收藏  举报