2016年2月6日 星期六

Javascript的原型

Javascript與我們熟知的Java及C++不同,它沒有Java及C++那種繼承(extends)與實作介面(implement interface)的概念,而是有自己獨特的「原型鏈」特性,對沒接觸過的人可能會有點難以理解,所以在這篇文我特地為其做了筆記。

在Javascript中,幾乎任何東西(除了Boolean, Number那些)都是類別(Obejct),而在類別中有三個有趣的屬性:constructor、prototype、_proto_。

當我們在使用「new」這個關鍵字時,就會用到以上三個屬性,例如:

var bus = new Car();

它的行為就是:

  1. 為bus建立一個實例(instance)。
  2. 將 bus._proto_ 指向 Car.prototype 。
  3. 將上下文設定成 bus (即this代表bus) 來執行 Car.prototype.constructor()。
為了容易理解,可以用下圖來表示:




對應的程式碼可能如下:
var Transportation = function(){......};
var Car = function(){......};
Car.prototype = new Transportation();
var car1= new Car();

當要使用的變數在bus中找不到時,它會去car1._proto_中去尋找,如果還是找不到,就會到
bus._proto_._proto_中去尋找,以此類推,直到找盡頭(XXX._proto_ = null)為止。

利用這樣的特性,就可以模擬(不完全相同)Java中的繼承關係,例如上例就有如 Car 繼承 Transportation、 bus 繼承 Car這樣的關係。

如果想要再創一個Bus去繼承Car的話,就可以像這樣:
var Bus = function(){......};
Bus.prototype = new Car();



參考資料:

  1. JAVASCRIPT原型
  2. 基於原型的JavaScript繼承
  3. javascript 原型模式的工作原理 到 對象模式的探尋(上)
  4. 實體關係的確定
  5. JavaScript's Pseudo Classical Inheritance diagram