Reflection
一個物件可以列出自己有哪些成員。
利用
Reflection
可以實現一個有用的模式,叫做extend
用來將一個物件的所有成員複製到另一個物件裡。
1 | var A = { |
for in可以將目標內的屬性全都遍歷、loop一輪,而現在要把 B
每個 屬性 property
和 值 value
都取出來
1 | B.__proto__ = A; |
B[prop]
是"."
運算子的另一種寫法,並不是陣列。
如B.fristname
也可以寫做B['firstname']
,因為這邊採用變數做歷遍的關係,因此只能使用[]
運算子。( 關於這部分可以參考 SimonAllen - Day12 物件與點 )
B其實沒有getFullName
這個方法,因為B
的原型物件A
有,for in還是順著原型鏈把其他屬性都取出來了。
我們可以用JavaScript物件內建的方法hasOwnProperty
來幫助我們篩選,將for in程式碼改成這樣
hasOwnProperty
可以檢查屬性,若是該物件本身的成員才會回傳 true,.__proto__
內的屬則回傳 false,因此這裡的 if判斷,console.log只會印出 B
本身有的屬性。
Extend
利用
Reflection
可以列出自己所有成員的方法,就可以實做extend
功能,用來合併多個物件的所有成員。extend
在各種函式庫都有實做,所以這邊我們不自己寫而是使用 underscore.js 提供的。
使用 extend後,物件john
獲得了另外兩個物件jane
、jim
的屬性與方法,並不是說john
去原型鏈查找,而是利用extend
函式新增了原本沒有的屬性,我們現在可以直接操作john
最初沒有的屬性了。
1 | var john = { |
結語
extend(s)
是 JavaScript 物件導向很重要的觀念、語法,ES6
已有新增內建的extends
函數,另外 ES6的 extends和 underscore.js的 extend並未衝突,因為差了一個 s字母。- 有
extend
可以用的話,就不需要每次都使用原型鏈了。