iT邦幫忙

2022 iThome 鐵人賽

DAY 10
1
Modern Web

致 JavaScript 開發者的 Functional Programming 新手指南系列 第 10

Day 10 :何謂 Immutable Data?(2):更新物件

  • 分享至 

  • xImage
  •  

在討論如何使用 Immutable 的方式來操作物件的狀態前,讓我們來思考另外一個狀況:還記得前端常常考的面試題淺拷貝、深拷貝嗎?

在這邊我們不會以深拷貝、淺拷貝的角度切入討論更新物件的方式,原因在於其實在實務開發中鮮少要完全拷貝某個物件的結構,單純為了獲得兩個記憶體不同,但資料結構一模一樣的物件,更多的是在不改動原始資料的狀況下,進行資料的處理。

因此,雖然不太會有真的要完整複製某個資料結構的狀況發生,但絕對會有很常需要「更新」物件的資料的時候,那要怎麼透過 Immutable 的方式,在資料彼此獨立、互不影響的狀況下來更新物件的內容呢?

在這個章節我們要來討論如何使用 ES6 以後的語法糖:展開運算子(Spread Operator)與其餘參數(Rest Parameter)來做到物件的更新。

ES6 展開運算子

在 ES6 後新增了一個運算子,可以幫助我們去展開物件、陣列原有的屬性或是元素,這是什麼意思呢?我們來看以下範例:

const box1 = {
	apple: 1,
	banana: 1,
};
const box2 = { ...box1 };
// box2 = {apple: 1, banana: 1}

展開運算子會將後方帶入的物件內容展開並去掉大括號,所以我們要再補一組大括號回去,此時我們就會獲得一組不僅資料結構相同,參考物件也不同的新物件。

但要注意的是,透過展開運算子展開的物件只能做到淺拷貝,若有兩層以上的階層,依然會有物件屬性值傳參考的狀況出現,為了避免這個狀況,盡量只進行單層物件結構的展開。

於是現在比起透過這樣的方式進行拷貝(實際上下方的範例並沒有進行拷貝的行為):

const box1 = {
	apple: 1,
	banana: 1,
};
const box2 = box1;
// box2 = {apple: 1, banana: 1}

我們可以透過展開運算子透過 Immutable 的方式複製物件了!

那我們要怎麼透過這個特性進行物件的更新呢?結合函式的概念我們現在可以這樣更新物件的值:

const box1 = {
	apple: 1,
	banana: 1,
};
const updateAppleInBox1 = () => ({...box1, apple: box1.apple+1});
console.log(updateAppleInBox1());
// output {apple: 2, banana: 1}

透過這樣的方式更新物件會發現,我們不僅得到了更新後的物件,且原始的物件也沒有被更改到耶!

那如果要刪除物件屬性怎麼辦呢?我們可以透過物件解構(Object Destructuring)搭配剩餘參數做到這件事:

ES6 其餘參數

其餘參數的樣子其實跟展開運算子長得一樣,只是會依據我們使用的場合而決定,要展開的是「所有的內容」或是被解構剩餘的剩下屬性值,搭配上方的概念,我們可以這樣使用其餘參數:

const box1 = {
	apple: 1,
	banana: 1,
};
const deleteApplePropInBox1 = () => {
	const { apple, ...rest} = box1;
	return {...rest};
};
console.log(deleteApplePropInBox1());
// output {banana: 1}

範例中,我們將不想要的屬性獨立出來,並且將剩下我們要保留的屬性透過其餘參數的運算子語法保留進 rest 變數中,最後透過展開運算子在空物件中展開 rest 並且回傳,這樣我們就可以依照 Immutable 的原則,在不改變原物件的狀況下,取得刪除屬性的新物件了!

但要注意的是,展開運算子、其餘參數盡量以單層物件的概念去操作,不然就會有共用參考位置的問題出現,一不小心就會更新錯資料。

為了避免物件的 Mutation,即便使用了展開運算子、其餘參數,也不要它們當作是萬用丹,要時常注意資料的層級問題。

其實講到這邊不難發現,範例越來越有被模組化的感覺了,但這其實還只是 FP 核心概念的冰山一角,在進入到其他概念前,我們也來看看如何透過依據 Immutable 的原則來進行陣列的更新!那我們下一章節見!

參考資料:

Functional Programming For Beginners With JavaScript


上一篇
Day 9 :何謂 Immutable Data?(1):關於 Immutable 與 Mutable(修正版)
下一篇
Day 11 :何謂 Immutable Data?(3):更新陣列
系列文
致 JavaScript 開發者的 Functional Programming 新手指南30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言