前言
這門課程推出的時候 ES6 還未問世,現在可以看到許多的框架都有 Extend 的概念,甚至 ES6 也有 Extends ,而本小節課程作者要用 underscore.js ,利用一個叫做 Reflection 的概念達成 Extend。
Reflection 與 Extend
Reflection 意思就是一個物件可以列出自身的屬性,並且改變當中的屬性、方法。而 JavaScript 物件有能力可以看自己的屬性和方法,而我們可以透過這樣達成一個很有用的模式,稱為 Extend (擴展、繼承) 。
讓我們先準備好一些程式碼,並引入 underscore.js
1 | var person = { |
首先使用 for in ( MDN 介紹) 迴圈,遍歷 john 物件內所有成員並且印出,讓我們看看現在 john 物件內有什麼東西。
為什麼 john 物件內會有在原型上的 getFullName 方法 ?
因為 for in
迴圈也會到原型上取用屬性和方法,因此不侷限於物件本身。
也可以透過 if 結合 hasOwnProperty 進一步篩選結果
1 | for(var prop in john){ |
這樣就可以單純取出在 john
物件上的屬性或是方法,如果不在自身物件上,就是在原型上、或者根本不在原型鏈上的任何地方。
這樣的概念可以讓我們做更多的事 - 補足原型繼承,接下來課程作者就使用 underscore 內的 extend
函式作為範例介紹, extend
可以將其他物件的屬性、方法新增給目標物件。
1 | var person = { |
這邊新增的 jane
、 jim
物件,並沒有將它們放入原型鏈,但 john
又想要能有它們的屬性或方法,於是可以這麼做:
1 | _.extend(john, jane, jim); |
如此一來 john
就有了 jane
、 jim
內的方法,而且原型 person
也還在。打開 underscore.js 觀察 extend
函式是如何處理這一塊的。
可以看到 createAssigner
是利用閉包的特性撰寫而成,而使用 extend
後,物件 john
被新增了另外兩個物件 jane
、 jim
的屬性與方法。
透過 extend
函式現在 john
可以使用原本不屬於自身的屬性以及方法了。
1 | console.log(john.getFirstName()); // John |