js繼承方式


JS是一門弱類型動態語言,封裝和繼承是他的兩大特性

1原型鏈繼承

將父類的實例作為子類的原型
1.代碼實現
定義父類:

// 定義一個動物類
function Animal (name) {
  // 屬性
  this.name = name || 'Animal';
  // 實例方法
  this.sleep = function(){
    console.log(this.name + '正在睡覺!');
  }
}
// 原型方法
Animal.prototype.eat = function(food) {
  console.log(this.name + '正在吃:' + food);
};

 

子類:

function Cat(){ 
}
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';

// Test Code
var cat = new Cat();
console.log(cat.name);//cat
console.log(cat.eat('fish'));//cat正在吃:fish  undefined
console.log(cat.sleep());//cat正在睡覺! undefined
console.log(cat instanceof Animal); //true 
console.log(cat instanceof Cat); //true

 

2.優缺點
簡單易於實現,但是要想為子類新增屬性和方法,必須要在new Animal()這樣的語句之后執行,無法實現多繼承

2 構造繼承

實質是利用call來改變Cat中的this指向
1.代碼實現
子類:

function Cat(name){
  Animal.call(this);
  this.name = name || 'Tom';
} 

2.優缺點
可以實現多繼承,不能繼承原型屬性/方法

3 實例繼承

為父類實例添加新特性,作為子類實例返回
1.代碼實現
子類

function Cat(name){
  var instance = new Animal();
  instance.name = name || 'Tom';
  return instance;
}

2.優缺點
不限制調用方式,但不能實現多繼承

4 拷貝繼承

將父類的屬性和方法拷貝一份到子類中
1.子類:

function Cat(name){
  var animal = new Animal();
  for(var p in animal){
    Cat.prototype[p] = animal[p];
  }
  Cat.prototype.name = name || 'Tom';
}

 2.優缺點

支持多繼承,但是效率低占用內存

5 組合繼承

通過調用父類構造,繼承父類的屬性並保留傳參的優點,然后通過將父類實例作為子類原型,實現函數復用
1.子類:

function Cat(name){
  Animal.call(this);
  this.name = name || 'Tom';
}
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;

6 寄生組合繼承

function Cat(name){
  Animal.call(this);
  this.name = name || 'Tom';
}
(function(){
  // 創建一個沒有實例方法的類
  var Super = function(){};
  Super.prototype = Animal.prototype;
  //將實例作為子類的原型
  Cat.prototype = new Super();
})();

7 ES6的extends繼承

ES6 的繼承機制是先創造父類的實例對象this(所以必須先調用super方法),然后再用子類的構造函數修改this,鏈接描述

//父類
class Person {
    //constructor是構造方法
    constructor(skin, language) {
        this.skin = skin;
        this.language = language;
    }
    say() {
        console.log('我是父類')
    }
}

//子類
class Chinese extends Person {
    constructor(skin, language, positon) {
        //console.log(this);//報錯
        super(skin, language);
        //super();相當於父類的構造函數
        //console.log(this);調用super后得到了this,不報錯,this指向子類,相當於調用了父類.prototype.constructor.call(this)
        this.positon = positon;
    }
    aboutMe() {
        console.log(`${this.skin} ${this.language}  ${this.positon}`);
    }
}

//調用只能通過new的方法得到實例,再調用里面的方法
let obj = new Chinese('紅色', '中文', '香港');
obj.aboutMe();
obj.say();

更多詳情請戳:JS繼承的實現方式


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM