大家都說 JavaScript 是 Prototype System,
也是時候來好好瞭解 JavaScript 如何用 Prototype System 實作 Class。
在 JavaScript 看到 constructor calls
,比較好的想法是當作 創造一個 Object 來綁定 function call
。
也不要
使用 based on 的字眼去做描述。
這些描述就是我們說的object-oriented programming(class-oriented, OOP)
,
所以我們用這種模式 coding ,可以說基本上是在做 copy operation (具體上有些差異,不過整個操作的模式大概就是 copy 的概念)。
想像一下,
問題:如果把你藍圖上的牆全部擦掉,建築物會如何?
Ans: 沒事,不影響。
問題:如果把你建築物上面多安裝一扇窗戶,原本的藍圖會如何?
Ans: 沒事,不影響。
原因:因為把建築物造出來,就是實例化(instantiated)了之後,建築物和藍圖就沒什麼關連了。
這個就是我們說得,傳統OOP之中對 Class 的認識。
一般討論 Class ,還會討論 parent , child classes,這就是我們常說的 inherited。
inheritance 也是基於複製的操作。
最常見的比喻是,
假設我有個小孩,我有一個兒子。
那麼,他出生之後就有我的 DNA。
他和我是不同的個體,他在學校摔倒腳受傷,我的腳不會跟著受傷。
但是,如果我有禿頭,他也有很大的機會禿頭,這個關聯的感覺就是 inheritance。
普遍上語言實作都會真實的 flatten ,因為會有效能考量。
flatten : 字面上來說,會複製關聯到每一個 instance,
因為這樣比把每一個 instance 關聯到原本的 Class 還要快,
而不是每次都會查看 dynamic class hierarchy chain。
只有在 多型(polymorphism) 的時候,才會真正維護調整 dynamic class hierarchy chain,這樣的做法叫做 Virtual table (在 C++)。
總結來說,class的關聯 隱含(implied) 著一種複製關聯(copy relationship)。
不要
使用 based on 的字眼去做描述。
這也就是我們說不要使用 based on
去描述 JavaScript 裡面的 constructor
,
因為你可能會覺得 JavaScript 裡面的 constructor
也是複製 prototype 的 instance
但是 JavaScript 從來不做 copy
,反而是連結 (linked to) 物件。
這是兩個完全相對的概念。
也是最多人寫 Class 遇到 bug 的原因。