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"));
特色:
     既能夠繼承實例的屬性和方法,也能夠繼承構造函數的屬性和方法
     子類實例能夠給父類傳參
     實例既是子類實例也是父類實例
     能夠實現多繼承
     函數可複用
     經過寄生的方式,去掉了父類的實例屬性,調用兩次父類構造函數時不會初始化兩屬性和方法
相關文章
相關標籤/搜索