React-在開始使用React要了解的事之四「不可變性」

何謂不可變性:

“Mutable(可變的)“代表是可以被改變的、修改的,而"Immutable(不可變的)“則是它的反義詞,代表所有資料不可以被改變或修改的。

JavaScript 並非是純粹的函式導向程式設計,在純函式導向程式設計語言中,所有的物件都是不可變的。在 JavaScript 中的設計是所有基本資料類型如 Undefined, Null, Boolean, Number, String, Symbol 是不可變的,但物件通常是可變的。但在 Array 中有些不可變的方法(意思是會回傳新的陣列,而非直接修改原陣列),今天這篇的學習文章為不可變性,在函式導向程式設計中,所有資料都是不可變動的。

舉例:

請想像一個情境: 你可能因為很開心考到駕照,想要 po 到社交平台上,但不想把駕照上有你的身分證的隱私資料曝光,這時候有兩種選擇:直接在駕照上塗改拍照;或是先拍照之後在照片上修改,正常都會走第二種也比較合理,不然辛苦考到的駕照剛拿到手就毀了還要補發,第二種方式既可以保持原本的駕照完好,又可以對拍好的照片資料作修改變動。這其實就是「資料的不可變動性」的概念,我們不直接修改資料,而是修改資料副本。

舉一個程式中的資料示範何謂變動資料,假設有個物件 sky 代表天空的顏色(一般來說):

let color_sky = {
  title: "sky",
  color: "0000FF",
  opacity: 1,
};

我們接著創造了一個函式 opacityColor,用以修改顏色的不透明度.opacity:

function opacityColor(color, opacity) {
  color.opacity = opacity;
  return color;
}
console.log(opacityColor(color_sky, 0.8).opacity); //0.8
console.log(color_sky.opacity); //0.8

在 JavaScript 中,函式接受引數會直接參照至資料本體,設定物件的屬性其實便意味著修改資料。

我們可以修改 opacityColor 函式,使它不要修改到原有的資料:

const opacityColor = (color, opacity) => ({
  ...color,
  opacity,
});
console.log(opacityColor(color_sky, 0.8).opacity); //0.8
console.log(color_sky.opacity); //1

在以上程式碼中我們透過延展運算子,來幫我們複製傳入的物件,這樣就能夠不變動到原本的 color_sky 物件,再使用 opacity 覆蓋原本的屬性。 總而言之,為了確保資料是不可變動的,我們會先複製一個副本,再針對副本做修改。

comments powered by Disqus