最新消息:XAMPP默认安装之后是很不安全的,我们只需要点击左方菜单的 "安全"选项,按照向导操作即可完成安全设置。

Javascript Mutable 跟 Immutable 資料型態

XAMPP下载 admin 876浏览 0评论
 Javascript 的 Mutable, Immutable 資料型態
之前談到純函數的第二個要件是不能對可改變(Mutable) 資料做變更,那在 Javascript 中有哪些資料型態屬於 Mutable 資料型態呢?我們先來看 Javascript 的資料型態

Javascript 的資料型態
Javascript 總共有七個資料型態

原始資料型態 (Primitive)
Boolean
Null
Undefined
Number
String
Symbol (new from ES6)
Object
所有的原始資料型態都是不可改變的(Immutable)
到底 Mutable 跟 Immutable 有什麼區別?先來看 Immutable 的例子

// for number
let a = 3;
let b = a;
b = b + 4;
console.log(‘b = ‘, b);   //  7
console.log(‘a = ‘, a);   //  3

// for string
let c = ‘This is original string’;
let d = c;
d = ‘Now change the string’;
console.log(‘d = ‘, d);   // Now change the string
console.log(‘c = ‘, c);   // This is original string
codepen
當其他變數(例如 b, d) 參照到原來變數 (a, c) 時,系統會在 Memory 指派一個新的位址,不會影響到原來的變數,那 Mutable 呢?

// for object
let e = { name: ‘John’, age: 40, title: ‘Engineer’};
let f = e;
f.title = ‘Manager’;
console.log(‘f = ‘, f); // { name: ‘John’, age: 40, title: ‘Manager’ }
console.log(‘e = ‘, e); // { name: ‘John’, age: 40, title: ‘Manager’ }
可以發現新的變數(f)還是指到原來變數(e)的位址,所以當f改變時,e也跟著改變了,這是為了系統的優化而作的。然而不小心的話,可能會造成程式的臭蟲(bug), 而很難去追蹤,想像同一個物件共用在不同的地方(在 Angular 不同的 Component 或 module 中),當一個地方改變這個物件時,其他地方如果不注意,沒有隨之更改(比如說狀態),就會造成使用者的困擾,而這有時候很難去除錯。

Javascript 的物件是 Mutable
Javascript 的物件有包含了很多類型,幾個常見的

Date
Indexed Collection: 陣列(Array) 跟 typed Array
Keyed Collection: Map, Set…
Structure Data: JSON

而這些在我們處理純函數時,都要特別留意小心。

純函數怎麼處理 Mutable
讓我們來看如何處理先前物件的例子

// immutable
let g = { name: ‘Mary’, age: 38, title: ‘Engineer’};
let h = Object.assign({}, g, { title: ‘Manager’});
console.log(‘h = ‘, f); // { name: ‘Mary’, age: 38, title: ‘Manager’ }
console.log(‘g = ‘, g); // { name: ‘Mary’, age: 38, title: ‘Engineer’}
使用Object.assign() 來產生一個新的物件,它的語法是Object.assign(target, …sources),我們的 target 是一個新的空的物件 {}, sources 是 g 跟{title: ‘Manager’},將 sources 結合後放入 target 中。這樣產生出來的變數h就跟原來的g脫勾了。
這個做法相當重要,往後我們在 Reducer 中,經常會見到這樣的語法。

陣列的處理
Javascript 的陣列是特殊的物件,當然也是 Mutable,比較特殊的是陣列有些 Operators 是 immutable的,例如 .map .filter .concat…,這些 Operators 會產生新的陣列,不會影響舊的陣列,我們可以直接用在純函數中。

然而有一些 Operator 是 mutable 的,例如 .push .pop .sort…,這些會直接改變原本的陣列,我們在純函數中就不該使用。

但是如果我們要加一個元素到陣列時,該怎麼做?看以下例子

// for array
let i = [1, 2, 3, 4];
let j = i;
j.push(5);
console.log(‘j = ‘, j);   // [1, 2, 3, 4, 5]
console.log(‘i = ‘, i);   // [1, 2, 3, 4, 5]

// immutable array
let k = [1, 2, 3, 4]
let l = […k, 5];
console.log(‘l = ‘, l);  // [1, 2, 3, 4, 5]
console.log(‘k = ‘, k);  // [1, 2, 3, 4]
codepen

如果直接用 .push會影響原來陣列,這就不能用在純函數,而使用擴展語法 spread syntax,會產生新的陣列,不會對原本陣列產生影響。

擴展語法是一個相當強大的語法,有提議將這種語法擴充到物件上,雖然目前瀏覽器的支援還不夠,但因為我們使用 Angular typescript,它會幫我們做轉換,所以還是可以安心使用,舉個例子,之前的 let h = Object.assign({}, g, { title: ‘Manager’}); 可以寫成 let h = {…g, title: ‘Manager’}

現在,我們對於純函數有了一些工具來建置,接下來我們來深入探討一下 ngrx/store 如何實作 Flux 的概念。

转载请注明:XAMPP中文组官网 » Javascript Mutable 跟 Immutable 資料型態

您必须 登录 才能发表评论!