js继承总结

js的继承方式(共6种):javascript

 

  定义一个父级函数:
function Animal(name){ this.name = name; this.sleep = function(){ console.log(this.name+"在睡觉") } } Animal.prototype.eat = function(food){ console.log(this.name+"再吃"+food); }

  第一种:原型链继承(父类实例做为子类的原型)java

function Cat(name){
    this.name = name;
}
Cat.prototype.color = "白色";
Cat.prototype = new Animal();
var cat1 = new Cat("Tom");   //  实例1
var cat2 = new Cat("Jim");    //  实例2
var cat3 = new Cat("Sun");    //  实例3
console.log(cat1.name);
console.log(cat1.color);   //  undefined
console.log(cat2.sleep());
console.log(cat3.eat("fish"))

特色:
     简单易实现
     父类实例的属性和方法子类均可以继承
缺点:
     想要新增原型属性和方法必须放在new Animal()语句以后
     不能实现多继承(一个子类同时继承多个父类)
     来自原型对象的属性是全部实例共享的
     建立子类实例时,没法向父类构造函数传参      
    

  第二种:构造函数继承(经过使用call改变this指向,指向父类实例,至关于复制父类实例的属性给子类)app

function Cat(name){
    Animal.call(this);
    this.name = name;
}
var cat1 = new Cat("Tom");
console.log(cat1.name);
console.log(cat1.sleep());
console.log(cat1.eat("fish"))   //  cat1.eat is not a function

特色:
     能够实现多继承
     建立子类实例时能够向父类传参
缺点:
     只能继承父类实例的属性和方法,不能继承原型的方法
     函数不可复用
     实例只是子类实例不是父类实例
    

  第三种:实例继承(为父类实例添加新属性,做为子类实例返回)函数

function Cat(name){
    console.log(this)
    var instance = new Animal();
    instance.name = name;
    return instance;
}
var cat1 = new Cat("Tom");
var cat2 = Cat("Jim");
console.log(cat1.name)   // Tom
console.log(cat2.name)   // Jim

特色:
     不限制调用方式,new 构造函数  或者直接调用子类函数  获得的都是一样的结果
缺点:
     不支持多继承
     实例是父类实例,不是子类的实例

第四种:拷贝继承(获取父类实例,经过循环父类实例,把父类实例的属性和方法都赋给子类)this

function Cat(name){
    var animal = new Animal();
    for(var p in animal){
        Cat.prototype[p] = animal[p];
    }
    Cat.prototype.name = name;
}
var cat1 = new Cat("Jim");
var cat2 = new Cat("Jim");
console.log(cat1.name);
console.log(cat2.eat("fish"));

特色:
     能够实现多继承
缺点:
     由于每次都要循环,形成内存消耗严重,效率低
     不能够枚举的属性方法就会获取不到

  第五种:组合继承(经过调用父类的构造函数,继承了父类的属性和方法,并保留了传参的优势,经过将父类实例做为子类的原型,实现了函数的复用)spa

function Cat(name){
        Animal.call(this);
        this.name = name;
    }
    Cat.prototype = new Animal();
    Cat.prototype.constructor = Cat;
//    console.log(Cat.prototype.constructor);
    var cat1 = new Cat("Tom");
    var cat2 = new Cat("Li");
    console.log(cat1.name);
    console.log(cat2.eat("apple"))
特色:
     既能够继承实例的属性和方法,也能够继承构造函数的属性和方法
     子类实例能够给父类传参
     实例既是子类实例也是父类实例
     函数可复用
缺点:
     调用了两次父类构造函数,生成了两份实例
     (1). 设置子类实例原型的时候  Cat.prototype = new Animal();
     (2). 建立子类实例的时候      var cat1 = new Cat("Tom");

  第六种:寄生组合继承prototype

function Cat(name){
        Animal.call(this);
        this.name = name;
    }
    (function(){
//      建立一个没有实例方法的类
        var Cate = function(){

        }
//      将父类原型当作这个类的原型
        Cate.prototype = Animal.prototype;
//      把实例做为子类的原型
        Cat.prototype = new Cate();
    })()
    var cat1 = new Cat("Tom");
    var cat2 = new Cat("Jim");
    console.log(cat1);
    console.log(cat2.eat("apple"));
特色:
     既能够继承实例的属性和方法,也能够继承构造函数的属性和方法
     子类实例能够给父类传参
     实例既是子类实例也是父类实例
     能够实现多继承
     函数可复用
     经过寄生的方式,去掉了父类的实例属性,调用两次父类构造函数时不会初始化两属性和方法
相关文章
相关标签/搜索