本文是第二篇,有些變數的名詞會沿用第一篇,建議看過再繼續閱讀唷!
上回提到,我們用物件的形式儲存了落葉的變數和函式,認識了物件的結構和定義方法,接著還利用建構式將產生落葉的流程給固定下來,並在每次滑鼠點擊時,都產生一個新的落葉物件:
let leaf;
canvas.addEventListener('click', SetMouse);
function SetMouse(e){
leaf = new leafMaker();
}
這個動作稱之為實例化,在談論這點之前,也要一併解釋一開始被我們稱之為「落葉產生器」的leafMaker,這個說法只是為了讓大家好懂,而實際的概念就讓我做個比喻吧!
想像你今天走進了一家拉麵店,然後點了一份豚骨拉麵,接著廚師按照食譜烹飪了這個美味的豚骨拉麵,端到了你面前,於是你大快朵頤了一番,好不快樂!
首先,我們把豚骨拉麵當作一個物件,它本身也有一些屬性,像是湯底由豬骨和蔬菜熬煮而成、拉麵為手工製作等等,由於這個豚骨拉麵你吃在嘴裡、感動在心裡,聞的到摸的到,它就是一個實體的存在;而與之對立的便是廚師手上的「食譜」,食譜本身不能吃(你能想像廚師把食譜放到你面前讓你嚐嚐看嗎),甚至它是一個抽象的概念,料理的步驟被廚師爛熟於心,因此,單從這個食譜來看,你無法知道它好不好吃,食譜本身也沒有湯底和拉麵。
終歸一句話,我們就想吃到美味的豚骨拉麵而已呀!因此便有了廚師(JS)存在的意義,它幫我們烹飪(new)了豚骨拉麵,將其實例化(才能吃)。到這邊就可以講白了,所謂按照食譜烹飪的這個指令就是new leafMaker(),JS則幫我們做出豚骨拉麵,與之對應的就是leaf,一開始我們設計的leafMaker,充其量就只是一個食譜、步驟而已,或者說是抽象的本質,因此自然落下這個概念不存在其中(leafMaker.fall),而是在於落葉的實體(leaf.fall)
人類與生俱來就具有將事物抽象化的能力,也因此自立於萬物之靈,物件模型就幫我們模擬了這個觀點,如果你去詢問一個務農的人「你覺得什麼是豚骨拉麵」,他可能會回答你:是食物、是賴以為生的重要養分;如果去問一個上班族,他可能會回答:是我的精神食糧,能治癒我的心靈;如果去問一個哲學家,他可能會回答:是慾望,是將美好作為誘餌投放的毒藥。
每個人或許有不同的觀點,但關鍵是在他們的理解中,都能解釋什麼是豚骨拉麵,並且有他們自己的論證,在JS中也一樣,為了能夠解釋什麼是豚骨拉麵,物件模型很好的聯繫了豚骨拉麵的抽象本質和實體存在,端看你如何定義,我們便可以使用一段代碼來描述上面這個例子:console.log(leaf instanceof leafMaker)
,我們會得到結果true,因為leaf確實是用leafMaker建構式實例化的物件,反過來也就是說,你問JS「什麼是leaf」,它能夠回答你:是以leafMaker為藍圖建構出來的實體。
你可能會感到困惑,豚骨拉麵都已經煮好了,回去探究是哪份食譜做出來的有什麼意義嗎?這個聯繫實際上相當重要,我個人會解讀成一個物件的過去、現在、未來,雖然當下的我們都處於現在,也就是你正在吃豚骨拉麵,但我們討論的範疇只是你在一家店吃豚骨拉麵,如果你在另一家店,不也是吃豚骨拉麵嗎?但是另一家店的食譜,會不太一樣對吧?所以時間還得倒退回到你踏進店門前,你決定要吃A店,不吃B店,這影響了你最終嚐到的豚骨拉麵味道不同,而物件模型神祕的地方,就在於,它能夠改寫你的過去,前一刻你還還在跟朋友說A店的豚骨拉麵好好吃,下一刻朋友就跟你說,這碗拉麵是B店的不是嗎?
這個例子說明了物件對抽象化的能力,不僅限於概念而已,還包含更深的層面,因為每一個物件都有它的起源,從過去影響現在、乃至於未來,這個概念是JS獨有的原型prototype,這是一個相對更加深入的話題,未來會有個章節專門講述:「使命必達先生的故事」