Design

Design
asp.net mvc

2019年2月21日 星期四

JavaScript 理解原型鍊(prototype chain)及繼承(inheritance)

前言

現在前端爆炸的年代,我們開發都依賴在巨人的肩膀上很多前端FrameWork我們甚至可以不用知道背後的原理,JavaScript最簡單一句話就是所有東西都是Object因為其實也不需要複雜的底層架構,但是作者Brendan Eich還是覺得需要有一種機制讓對象串聯起來,所以就有原型鍊的出現,跟new class的出現,ES6的class其實是語法糖,不像Java C++  這類泛用程式有完整的繼承方式,java c++ new class後面都是調用我們"類"的建構函數(constructor),但JavaScript的new class其實調用的是我們的建構函數(constructor) function,就像我剛說的JavaScript的class其實就是語法糖,這就是當初作者為了完善語言所做的,好的 我們就來理解一下JavaScript的底層吧.

原型鍊(prototype chain)

在我們寫JavaScript時一定都會發現我們都有個__proto__這就是我們的原型鍊






接下來我們就可以簡單說明一下

function DOG(name){
    this.name = name;
  }  

//__proto__
DOG.prototype = { species  : '犬科' , jump:function JUMP(){
  }};

//constructor
var dogA = new DOG('大毛'); 
var dogB = new DOG('小黑'); 
console.log(dogA); 
console.log(dogA.name) // 大毛 原本的物件指定屬性
console.log(dogA.species) //犬科 原本的物件指定屬性 沒有就往__proto__找
console.log(dogB) // 犬科 可以發現我們prototype的species跟jump變成共用的方法

可以把__proto__想成有建構DOG這個函數都會有的內共用的屬性或方法  印出dogB.species 雖然我們沒有原本物件屬性沒有但我們一樣可以從__proto__裡面找到我們的species跟jump  大致上會長跟下面一樣

所以簡單一句話說就是 建構的dogA跟dogB都可以共用到我們proto的內容 , 然後找屬性的順序就是從我們原本的物件有的屬性 例如舉例的name開始找 沒有再從__proto__下面找這樣一層一層的下去




繼承(inheritance)

上面是樣的建構函數我們的__proto__可以共用屬性或方法,今天要是不同建構函數我們又想要共用這時就需要我們的繼承了 我們可以先看看ES5跟ES6的差異,ES6更加直覺 也跟C#越來越像,最後可以發現我們也讓不同建構函數達到了跟java c++一樣的繼承效果
//ES5

//父類別 狗的種類
function DogBase(){
    this.name = "狗名字";
    this.color = "black"
    this.age = "1"
}
//共用跑的方法 
DogBase.prototype.Run = function(){
    return "跑"
}

//子類別 黃金獵犬
function GoldenRetriever(name){
  //我們可以去繼承父類的基本屬性 
   DogBase.call(this);  
    this.name = name;
}

//今天我也想要讓 黃金獵犬有Run的方法 
//GoldenRetriever去繼承Chihuahua
GoldenRetriever.prototype = new DogBase;

//构造实例
var es5 = new GoldenRetriever("黃金獵犬"); 
console.log(es5);
console.log(es5.Run());
//ES6

//父類別 狗的種類
class DogBase{
   constructor(name, color, age,run) {
    this.name = "狗名字";
    this.color = "black"
    this.age = "1"
    this.Run = function(){
    return "跑"
    }
  }
}

//子類別 黃金獵犬
class GoldenRetriever extends DogBase{
   constructor(name) {
    super('color', 'age','run')
    this.name = name;
   }
  //我們可以去繼承父類的基本屬性 
}


//构造实例
var es6 = new GoldenRetriever("黃金獵犬"); 
console.log(es6);
console.log(es6.Run());






參考資料來源
https://ssarcandy.tw/2017/12/06/javascript-prototype-chain/
https://pjchender.blogspot.com/2016/06/javascriptprototypeprototype.html
http://www.ruanyifeng.com/blog/2011/06/designing_ideas_of_inheritance_mechanism_in_javascript.html
https://segmentfault.com/a/1190000015766680
http://es6.ruanyifeng.com/#docs/class-extends

沒有留言:

張貼留言