1.构造函数式继承 -- 在子类的构造函数中执行父类.call(this)

        function Dog (name){
            Animal.call(this);//在子类的构造函数作用域中执行父类的构造函数
            this.name=name||"Tom";//干掉了父类的name
        };
        var doggy = new Dog('Wangcai');

        console.log(doggy.name);//Wangcai
        doggy.sleep();//Wangcai正在睡觉!
        console.log(doggy.eat());//没有此方法,此行报错
        console.log(doggy instanceof Animal); // false
        console.log(doggy instanceof Dog); // true
        console.log(doggy);  

特点:可以实现多继承(call多个父类对象)

实例并不是父类的实例,只是子类的实例;
只能继承父类构造函数上的属性和方法,不能继承父类原型对象上的属性和方法;

 

2.原型链继承(又名类式继承)--借助原型链,子类的原型对象是父类的实例

       //父类Animal
       function Animal(name){
               this.name=name||"Animal";
               this.sleep=function(){
               console.log(this.name+"正在睡觉!");
               };
           };
        Animal.prototype.eat=function(food){
            console.log(this.name+"正在吃"+food);
        };

        // 原型链继承(又名类式继承)
        // 子类Cat
        function Cat(name){
            this.name=name||"Tom";
        }
        Cat.prototype=new Animal();//子类的原型对象是父类的实例
        var cat=new Cat('Kitty');//创建子类Cat的实例cat
        cat.sleep();//Kitty正在睡觉!
        cat.eat('屎');//Kitty正在吃屎
        console.log(cat);

        var catty = new Cat('Mimi');//创建子类catty
        console.log(catty.prototype === cat.prototype);//true

        //子类Tiger
        function Tiger(){
            this.name='laohu';
        };

        Tiger.prototype=new Animal();//子类的原型对象是父类的实例
        var tiger = new Tiger();//创建子类Tiger的实例tiger 

        console.log(Tiger.prototype == Cat.prototype);//false
        console.log(cat.name);//Kitty
        console.log(cat);
        console.log(cat instanceof Animal); //true 
        console.log(cat instanceof Cat);//true

优点:
 非常纯粹的继承关系,实例是子类的实例,也是父类的实例。 父类新增方法属性,子类都能访问到。

缺点:
不能继承父类构造函数,构造函数上的属性不能继承,无法实现多继承。


3.拷贝继承/组合式继承(原型继承+构造函数式继承)-- 前两种方式加起来

        function Bird(name){
            Animal.call(this);
            this.name=name||"Tom";
        }
        Bird.prototype=new Animal();
        var xique=new Bird();
        console.log(xique);
        console.log(xique.name);
        console.log(xique.eat());
        console.log(xique.sleep());
        console.log(xique instanceof Bird);
        console.log(xique instanceof Animal);

既可以继承父类构造函数上的属性和方法,又能继承父类原型对象上的方法,但是父类构造函数执行了两次。

4 寄生组合式继承

写法一

    function Bear (name){
        Animal.call(this);//构造函数式继承
        this.name=name||"Tom";
    }
    (function(){
       var Super =function(){}//寄生类
       Super.prototype=Animal.prototype;
       Bear.prototype=new Super();
    })()
    var cat = new Cat();
    console.log(cat.name);
    console.log(cat.sleep());
    console.log(cat instanceof Animal); // true
    console.log(cat instanceof Cat); //true

写法二

     var Train = function(){
            this.color='yellow';
            this.price='150000';
            this.p='属性';
        };
        Train.prototype.sell=function(a){
            var str = this.color+'的火车卖给了'+a+'卖了'+this.price;
            console.log(str);
        };

        var harmony = function(){
            Train.call(this);
        };
    
        harmony.prototype = Object.create(Train.prototype,{
            constructor:{
                value:harmony,
                enumerable: false,
                writable: true,
                configurable: true
            }
        });//修正constructor
        var h = new harmony();
        console.log(h);
        console.log(h.color);
        h.sell('yuanyuan');

避免了组合式继承父类构造函数执行两次的问题。

 posted on 2019-02-20 15:08  ElenaWang  阅读(238)  评论(0)    收藏  举报