更新於 2024/11/04閱讀時間約 9 分鐘

Day07 JavaScript Returning 與 Mutating Function


在開始討論這兩個陌生的名詞之前,我們先準備一份資料以便後續測試使用。

這筆資料是users的資料,可能是社群平台用來記錄使用者資料的格式。其中users是一個array([]包著),裡面包含了3個Object({}包著),每個Object內有許多的property-value配對(如id: 3username: “kbrunton2”等),以逗號分隔,換行只是因為方便閱讀。


接著使用之前講過,每個array內建的push()method,將一筆新的資料放進users的最後。然後用console.log()來看看users裡面現在是什麼。

我用瀏覽器的Console,每個瀏覽器的Console顯示出來的可能稍有差異。

我們會發現users現在有編號0-3(紫色的數字),是總共4筆使用者資料的array了。


這不是什麼新內容,我們之前就學過array裡包含著object的情況,也見過array的push()method。現在再次提到,是因為這就是了解Mutating FunctionReturning Function的絕佳範例。

Mutating vs Returning

Mutating的意思「改變」,Mutating Function的意思是這個function會改變原本的值。以push()為例,本來只有3個內容的的arrayuserspush()這個method改變成4個內容。特別的事,push()做的不只是這樣,它還會Return(回傳)一個數值,被改變過後的array的長度(在這個情況就是4)。


我們可以把整串給印出來,看看這是如何運作的。

users.push()會回傳新array的長度(4),這個數值被console.log()印在Console裡面,我們就會看見4。像這樣會回傳一個值的function被稱作Returning Function。


你會發現push()method同時擁有兩種身份,它是Mutating Function,也是Returning Function。這件事情為什麼那麼重要?因為JavaScript內建常用的method行為各有差異,有些只是Mutating Function,有些是Returning,有些就像這個例子,兩者都是。光是事先了解一個method是哪種類別,你就可以預測它的行為。

有些人會覺得JS這樣的設計是靈活的,有些人覺得是凌亂的,褒貶不一。

重要的常見Method

Map

map()是其中一個array內建的method,它幾乎就是最常見的那個。map()常常用在將array資料根據某種條件複製一份。舉例來說,假設我只需要上述users的資料中name的那一項,而且也想將這些使用者的name存成array的形式,就很適合使用map()


我們可以這樣寫:

每個array都內建map()這個method。

map()會根據條件回傳一個新的array,它不會Mutate(變更)原本的users array。換句話說map()是一個Returning Function而不是Mutating Function。而map()會需要一個function作為參數,讓它知道根據什麼條件回傳,因此它也是一個Higher-Order Function。我們繼續看下去。


map()裡面需要一個function作為參數,我們定義一個onlyNameTest()來供它使用。map()會做的事就是對每一個usersarray裡的元素做一次onlyNameTest()這個操作,然後把onlyNameTest()回傳的內容放進新的array裡面。


以目前的情況為例,這個onlyNameTest()會執行4次(因為usersarray有4個元素),每一次都會回傳”hello”,放進新的array裡面。

結果就是newArray裡面會有4個”hello”


現在我們來嘗試製作一個只有username的新array。

我們一樣使用map()來根據舊的array產生新的。其中users裡的每個項目都會被onlyName()function作為參數使用,我們把參數命名成user。接下來只要回傳每一個userusername這個property就可以了,.來存取username


最後把這個結果儲存到新的arrayusersOnlyName,並印在Console。

成功得到一個新的長度為4的array,裡面只有username而且原本的usersarray並沒有被改變

Filter

filter()在各方面都跟map()很類似,它一樣是array的method、會回傳一個新的array、需要另一個function作為參數等等。

假設我們現在想要找出所有gender: “Female”的資料,並且同樣存在array裡面,filter()完美的完成這個任務。

同樣的,在filter()參數這裡我們傳給它一個functiononlyFemale(),讓它重複執行,在這情況下它一樣會執行4次(因為array的長度是4)。跟map()不同的是,filter()的機制是根據onlyFemale()回傳的結果true或是false來決定要不要把內容放進新array


用這個user.gender == ‘Female’ 條件判斷是不是該保留。最後就可以得到gender: ‘Female’的新array了。

可以發現array的長度剩3,因為在users裡面只有3個gender: ‘Female’的資料,它們被filter()成功的過濾出來了。

連續使用

到這裡可能還是讓人困惑,到底為什麼要特別介紹幾個method?主要是這對我們了解HOF在JS的運作很有幫助,因為第一眼見到以下的內容會顯得很奇怪。

我們再接著定義另一個function用來filter,這個function叫做onlyIdLargerThanTwo()用來找到id > 2的user。

從這段可以看見一個JavaScript特殊的使用方式,我連續使用了兩個filter()。由於第一個filter()是Returning Function會回傳一個新array新的array又可以用filter()method,可以一直按照這種方式接續下去,變成一個chain(鏈)


由於map()也是Returning Function,我們也可以在後面加上map(),並使用一開始定義的onlyName()function只留下名稱。

換行只是方便閱讀而已。

最後呈現出來的結果就是符合gender: 'Female'又符合id > 2的使用者的username


這種連續使用的情境在JS裡面屢見不鮮,由於這些內建的method都是會回傳array的Returning Function,才得以實現這種寫法,這也是我們特別介紹特定這幾個method的原因。第一次見的人可能會無法理解為什麼寫了一長串。

小結

在今天的內容裡,我們了解什麼是Mutating FunctionReturning Function。其中很特別的是Returning Function在某些特定的情況下可以連續的使用、串接在一起,這是JavaScript裡面很常見的操作,而且不僅限於在array上運用。這讓map()filter()之類的method,即使不變更原來array的值(not mutating),依然強大好用。


明天,我們會討論Context & Scope,這是連資深工程師都可能需要花點時間釐清的部分,我們會一一討論。


Resource

今日Codepen

連結

Credits

關於我

我是Erkin, 一個網站開發者。
有任何疑問或是想勘誤的話歡迎聯繫。

分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.