iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 23
0
Modern Web

那些年,我們一起錯過的Javascript系列 第 23

Day23_先別管鐵人賽拉,你們看過新的勞基法了嗎。

prototype

Prototype可以說是Javascript至關重要的一環,嚴格來說Prototype不管在哪個程式語言都是很重要的觀念,但Javascript的prototype觀念又跟多數的程式語言有著特別的不同。

今天就來討論一下最根本的觀念,Object-oriented Javascript & Prototypal Inheritance。

當提到了object-oriented,我們主要會專注在物件的創造,因為這個Part藏著許多讓人混淆的部分。

Inheritance

首先我們先理解繼承的概念,Javascript內的繼承核心概念就是,是一個物件可以access到另一個物件的property、method。

Classical Inheritance

如果你學過Java或者其他程式語言,相信你對class一定不陌生,透過class可以分享methods & properties給class的instance。

但聰明的你一定發現,這樣的繼承方式顯得有點冗贅,並且容易交互影響,很難去搞明白這群物件們是怎麼與彼此互動的,你得搞明白許多keywords protected、private、interface、blablabla。

並不是說classical的方式就是不好,它肯定有它的好處才會這麼受歡迎,只是仍然有些不足的部分。

Prototypal Inheritance

Prototypal Inheritance,它相對的易於使用,並且容易修改或者擴增,以及容易理解其中的脈絡,但也不是完美無缺的,相對的結構比較鬆散,一不注意就會讓整個結構變的混亂。

Again

當我們提到Javascript的 inheritance時,我們就只在意一個最核心的觀念,也就是,一個Object 可以 access 另一個object 的 properties & methods.

想更清楚明白剛剛提到的兩種繼承差異,請服用下面這篇文章。

What’s the Difference Between Class & Prototypal Inheritance

Understanding the prototype

到底什麼是prototype呢,我們知道Javascript的物件都有properties,而實際上Javascript內的物件都有一個prototype property - proto

proto 主要是連結到其他物件的一個reference,而它也就是我們的prototype,看下圖。

https://ithelp.ithome.com.tw/upload/images/20180111/20107670uSiYNq3Jwe.png

今天我們obj.prop2若在原本的obj內找不到的話,則會往proto去尋找,也就是往prototype去找,借由proto再去看看有沒有一個property name,有的話則reutrn回來。

就片面來看我們會以為obj含有prop2,但實際上prop2是存在於object prototype裡面。

同時,proto這個物件可以再指到另一個proto,每個物件都有自己的prototype,可以一直延展下去,prototype的prototype可能也有其它property。

https://ithelp.ithome.com.tw/upload/images/20180111/201076708YxT2OfCuk.png

這樣一層一層prototype組織而成的鍊子,就稱為prototype chain - 原型鍊。

而這個原型鍊通常是藏住的不會被看到的,也就是我們不會打 obj.proto.proto.prop3,而只要obj.prop3就會得到,Javascript Engine會透過原型鍊去尋找property & method。

而不一樣的Object卻有可能擁有同樣的proto。

https://ithelp.ithome.com.tw/upload/images/20180111/20107670calC33POW2.png

我們知道proto只是一個reference,所以我們share到的同樣的property,不論是 obj.prop2 or obj2.prop2指到的都是同樣的記憶體位置,同樣的property。

這就是原型鍊,也就是prototype的概念,就這樣,別想太多,就是一個object會有reference到proto去,這個proto可能含有其他property & methods,但不用記得它再哪,Javascript Engine會自動透過prototype chain幫我們找。

還是要Sample一下

https://ithelp.ithome.com.tw/upload/images/20180111/20107670t59BCl62bm.png

範例中,我們主動將john的prototype設為person,因此儘管john物件中沒有greet(),仍然可以透過prototype chain 去使用prototype裡面的method,也就是共享。

https://ithelp.ithome.com.tw/upload/images/20180111/20107670VPDQskyChO.png

而當我們取用firstName這個property時,為什麼不是得到Default呢? 這是因為,Javascript Engine會先尋找物件裡是否有此property,若沒有才會透過prototype chain去尋找。


今天就QQQ到這裡了,看起來是不是有點似懂非懂阿,但是我相信,多看幾次一定可以稍稍明白的,後面我們會再針對更細節做討論,今天先理解個大概消化消化,就這樣嚕,掰鋪。

參考來源

  1. Udemy Course - JavaScript: Understanding the Weird Parts
  2. You don't know JS

上一篇
Day22_褲子快掉了
下一篇
Day24_Prototype,很不Pro的筆記
系列文
那些年,我們一起錯過的Javascript30

1 則留言

0
阿陰
iT邦新手 5 級 ‧ 2018-01-11 23:59:08

可惡,被標題騙進來,結果還是在講鐵人賽啊 /images/emoticon/emoticon09.gif

好 偷一天來偷渡勞基法

可惡被標題騙進來 +1

我要留言

立即登入留言