面向对象的继承

一,普通继承:

继承思想:通过改变父类的执行环境,调用父类的构造函数,并改变父类的this指向。

<script>
    //创建一个父类对象:
    function Father(){
       //添加属性:
       this.heritage = 8888888888888888;
       this.skill = function(){
           console.log('经营一家上市公司');
       }
    }
    //创建一个子类对象:
    function Son(){
       //添加一个属性,指向父类的构造函数
       this.inheritor = Father;
       //在子类中调用父类构造函数:
       this.inheritor();
       //执行完父类构造函数后,inheritor属性对子类来说无用,可以删掉,
       delete.this.inheritor;
    }
    //new一个继承人对象:
    var s1 = new Son();
    console.log(s1.heritage,s1.skill());
</script>

缺点:父类中可变的属性,子类在继承属性时,值为undefined;

<script>
    //创建一个父类对象:
    function Father(name){
       //添加属性:
       this.heritage = 8888888888888888,
       this.name = name;
       this.skill = function(){
           console.log('经营一家上市公司');
       }
    }
    //创建一个子类对象:
    function Son(){
       //添加一个属性,指向父类的构造函数
       this.inheritor = Father;
       //在子类中调用父类构造函数:
       this.inheritor();
       //执行完父类构造函数后,inheritor属性对子类来说无用,可以删掉,
       //delete.this.inheritor;
    }
    //new一个继承人对象:
    var s1 = new Son();
    console.log(s1.name);//undefined
</script>

要解决上面出现的小bug,就需要借助call,apply,bind来继承。

二,构造函数继承(call,apply,bind继承):

继承原理:在子类中使用call和apply方法调用父类,并改变this指向,使其指向子类new出来的对象。

1.call继承:

用法:父类.call(this指向,继承属性)

<script>
    function Father(name,age,tel){
        //实例属性:
       this.name = name,
       this.age = age,
       this.tel = tel;
       //实例方法:
       this.running = function(){
           console.log('经营一家咖啡厅');
       }
    }
    function Son(name,age,tel){
        Father.call(this,name,age,tel);//调用父类构造函数,改变this指向为Son构造出的对象S1
    }
    var s1 = new Son('jinzi','88','123XX');
    var s2 = new Son('yinzi','89','124XX');
    console.log(s1,s2);
</script>

2.apply继承:

用法:父类.apply(this指向,[继承属性]/arguments)

<script>
     function Father(name,age,tel){
        //实例属性:
       this.name = name,
       this.age = age,
       this.tel = tel;
       //实例方法:
       this.running = function(){
           console.log('经营一家咖啡厅');
       }
    }
    function Son(name,age,tel){
        //Father.apply(this,[name,age,tel]);//调用父类构造函数,改变this指向为Son构造出的对象S1
        Father.apply(this,arguments);//arguments是参数副本,在使用参数副本时要注意:所有传递参数的位置保持一致。

    }
    var s1 = new Son('jinzi','88','123XX');
    var s2 = new Son('yinzi','89','124XX');
    console.log(s1,s2);   
</script>

3.call和apply的区别:

call的参数不固定;

apply的参数是一个数组或arguments(参数副本)

4.bind继承:

用法:父类.bind(this指向)(继承属性)

<script>
     function Father(name,age,tel){
        //实例属性:
       this.name = name,
       this.age = age,
       this.tel = tel;
       //实例方法:
       this.running = function(){
           console.log('经营一家咖啡厅');
       }
    }
    function Son(name,age,tel){
        Father.bind(this)(name,age,tel);
    }
    var s1 = new Son('jinzi','88','123XX');
    var s2 = new Son('yinzi','89','124XX');
    console.log(s1,s2);   
</script>

 三、原型链继承:

<script>
     function Animal(name,age){
         //实例属性:
       this.name = name;
       this.age = age;
         //实例方法:
    //    this.running = function(){
    //        console.log('eating');
    //    }
     }
     //原型方法:
     Animal.prototype.running = function(){
         console.log('sleeping');
     }
     function Dog(name,age){
        
     }
     //让子类的原型对象指向父类的实例:
     Dog.prototype = new Animal('niuniu',4);
     var niuniu = new Dog();
     console.log(niuniu.running());
</script>

注意:在使用原型继承时,如果父类的属性值不固定,继承时,子类无法更改这些属性值。要解决这个问题需要构造函数继承和原型链继承结合起来使用。

四,混合继承——构造函数+原型链继承:

<script>
        function Animal(name,age){
            //实例属性:
          this.name = name;
          this.age = age;
            //实例方法:
       //    this.running = function(){
       //        console.log('eating');
       //    }
        }
        //原型方法:
        Animal.prototype.running = function(){
            console.log('sleeping');
        }
        function Dog(name,age){
            //构造函数继承
           Animal.call(this,name,age);
        }
        //让子类的原型对象指向父类的实例:
        //原型继承:
        Dog.prototype = new Animal();
        var niuniu = new Dog('niuniu',4);
        var maomao = new Dog('maomao',8);
        console.log(niuniu.running());
        console.log(maomao);
   </script>

 五、es6继承:

<script>
    //定义父类:
    class Animal{
        constructor(name,color){
            //属性:
            this.name = name,
            this.color = color
        }
        //方法:
        eat(){
            console.log('吃鱼')
        }
        running(){
           console.log('奔跑')
        }
    }
    //定义子类,继承父类Animal;
    class Dog extends Animal{
        constructor(name,color){
            super(name,color);//继承父类所有的属性和方法
        }
    }
    var damao = new Dog('damao','grey');
    var ermao = new Dog('ermao','black');
    console.log(damao,ermao);
    damao.eat();
    ermao.running();
</script>
原文地址:https://www.cnblogs.com/kinoko-1009/p/10364573.html