iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 30
0
自我挑戰組

你為什麼不問問神奇 JavaScript 呢?系列 第 30

Day30 - 原型繼承

原型式 ( Prototypal ) 繼承

如果沒有近似繼承的方法用,那會顯得有點空虛。

( 那到底為什麼要和物件導向切割得這麼乾淨呢? )

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

Foo.prototype.myName = function() {
    return this.name;
}

function Bar( name, label ) {
    Foo.call( this, name );
    this.label = label;
}

Bar.prototype = Object.create( Foo.prototype );

Bar.prototype.myLabel = function () {
    return this.label;
}

var a = new Bar( "a", "obj a");

a.myName();  // "a"
a.myLabel(); // "obj a"

程式會照這樣的邏輯跑

  1. 第一個 RHS 查找。 Bar( "a", "obj a")。經過 new 繫結。得到 this 指的是 Bar 物件。
  2. Foo.call( this, "a" ),會得到 Bar.name = "a"。
  3. 回到 Bar,得到 Bar.label = "obj a"。
  4. 這些結果都會 assign 給 a。
  5. 執行 a.myName,沒在 a 找到 .myName 屬性,往鏈上找到 Bar 也沒找到 .myName,在往鏈上找到 Foo.myName,回傳 this.name,得到 "a"。
  6. 執行 a.mylabel,沒在 a 找到 .myLabel 屬性,往鏈上找到 Bar.myLabel,回傳 this.label,得到 "obj a"。

這樣對嗎? 來繼續看下去。

(但肯定不是下面兩種)

  1. Bar.prototype = Foo.prototype
  2. Bar.prototype = new Foo()

檢視「 類別 」關係

如果要真正了解 a 的歸屬,就要看他的繼承世系 ( inheritance ancestry )。其他類別導向的環境稱為 introspection。

設定如下。

function Foo() {
    // ..
}

Foo.prototype.blah = ...;
var a = new Foo();

來找 a 是什麼吧!

a instanceof Foo; // true

instanceof 運算子回答的是
a 再找個原型鍊上,Foo.prototype 指向的物件是否存在?

結語

鐵人賽的最後一天,依然是匆促趕稿中。
其實還有相當多缺漏的地方,之後會一一補齊。
第一次感受除了快速吸收知識以外,還要能夠將知識轉換出去的緊湊感。
每天一個章節,是一開始下得豪語。後來發現真的會哭得下豪雨。
後來漸漸的變成了花固定的時間,寫出已經吸收的內容。
謝謝大家這 30 天的陪伴,看著點閱數和訂閱增加,蠻有成就感的。

Tony 會繼續調整以往的內容。再把第二本也完整的補完。

參考資料

  1. 你所不知道的JS
  2. 克服 JavaScript 奇怪的地方

上一篇
Day29 - 原型
系列文
你為什麼不問問神奇 JavaScript 呢?30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言