Immutable.js 基礎(chǔ)操作

本文主要整理了Immutable.js常用API的使用。

Immutable 是什么疙描?

簡(jiǎn)而言之

  • Immutable數(shù)據(jù)就是一旦創(chuàng)建管行,就不能更改的數(shù)據(jù)格带。
  • 每當(dāng)對(duì)Immutable對(duì)象進(jìn)行修改的時(shí)候囊蓝,就會(huì)返回一個(gè)新的Immutable對(duì)象饿悬,以此來(lái)保證數(shù)據(jù)的不可變。

因?yàn)镮mmutable的官方文檔有點(diǎn)晦澀難懂聚霜,本文只是用來(lái)整理Immutable常用的API的使用狡恬,便于使用與查詢,想了解更詳細(xì)的內(nèi)容蝎宇,請(qǐng)戳這里~

Immutable 的幾種數(shù)據(jù)類(lèi)型

  1. List: 有序索引集弟劲,類(lèi)似JavaScript中的Array。
  2. Map: 無(wú)序索引集姥芥,類(lèi)似JavaScript中的Object兔乞。
  3. Set: 沒(méi)有重復(fù)值的集合。
  4. Record: 跟普通JS對(duì)象差不多撇眯。1报嵌、只是每個(gè)key都有一個(gè)默認(rèn)值,可被覆蓋熊榛。2、當(dāng)刪除一個(gè)key時(shí)腕巡,只是將其value置為默認(rèn)值玄坦,該屬性不會(huì)從對(duì)象上刪除。3绘沉、key是固定的煎楣,一旦創(chuàng)建后就不會(huì)增加或減少。4车伞、可以通過(guò)點(diǎn)運(yùn)算來(lái)獲取對(duì)象的屬性

用的最多就是List和Map择懂,所以在這里主要介紹這兩種數(shù)據(jù)類(lèi)型的API。

API的使用

1.fromJS()

作用:將一個(gè)js數(shù)據(jù)轉(zhuǎn)換為Immutable類(lèi)型的數(shù)據(jù)另玖。

用法:fromJS(value, converter)

簡(jiǎn)介:value是要轉(zhuǎn)變的數(shù)據(jù)困曙,converter是要做的操作表伦。第二個(gè)參數(shù)可不填,默認(rèn)情況會(huì)將數(shù)組準(zhǔn)換為L(zhǎng)ist類(lèi)型慷丽,將對(duì)象轉(zhuǎn)換為Map類(lèi)型蹦哼,其余不做操作。

代碼實(shí)現(xiàn):

    const obj = Immutable.fromJS({a:'123',b:'234'})

2.toJS()

作用:將一個(gè)Immutable數(shù)據(jù)轉(zhuǎn)換為JS類(lèi)型的數(shù)據(jù)要糊。

用法:immutableValue.toJS()

3.is()

作用:對(duì)兩個(gè)對(duì)象進(jìn)行比較纲熏。

用法:is(map1,map2)

簡(jiǎn)介:和js中對(duì)象的比較不同,在js中比較兩個(gè)對(duì)象比較的是地址锄俄,但是在Immutable中比較的是這個(gè)對(duì)象hashCodevalueOf局劲,只要兩個(gè)對(duì)象的hashCode相等,值就是相同的奶赠,避免了深度遍歷鱼填,提高了性能。

代碼實(shí)現(xiàn):

import { Map, is } from 'immutable'
const map1 = Map({ a: 1, b: 1, c: 1 })
const map2 = Map({ a: 1, b: 1, c: 1 })
map1 === map2   //false
Object.is(map1, map2) // false
is(map1, map2) // true

4.List 和 Map

創(chuàng)建

  • 直接用fromJS將原生轉(zhuǎn)成 List 或 Map
  • 構(gòu)造函數(shù)List车柠、Map
const list = List([1,2,3])
const map = Map({a:1,b:2})

取值/設(shè)值/刪除/ 清空/大小 get/set/delete/clear/size (size為屬性剔氏,其他為方法)

  • 用 toJS 轉(zhuǎn)原生后再操作
  • get(key)
list.get(0)  // 1
map.get('a')  // 1
  • getIn([]) 對(duì)嵌套對(duì)象或數(shù)組取值,傳參為數(shù)組竹祷,表示位置
let abs = Immutable.fromJS({a: {b:2}});
abs.getIn(['a', 'b']) // 2
abs.getIn(['a', 'c']) // 子級(jí)沒(méi)有值

let arr = Immutable.fromJS([1 ,2, 3, {a: 5}]);
arr.getIn([3, 'a']); // 5
arr.getIn([3, 'c']); // 子級(jí)沒(méi)有值

5. 使用注意點(diǎn)

1.變量命名

非常值得注意的一個(gè)點(diǎn)谈跛。因?yàn)榭赡芤昧似渌膸?kù)或者文件,使得代碼里存在immutable數(shù)據(jù)和非immutable數(shù)據(jù)。所以immutable變量需要加上 $$ 前綴來(lái)區(qū)分

2.API上的習(xí)慣

賦值操作之后要修改原數(shù)據(jù)記得要賦值塑陵。不然無(wú)法更新數(shù)據(jù)感憾。

$$data = $$data.set("hello","immutable")

3.為了性能和節(jié)省內(nèi)存, Immutable.js 會(huì)努力避免創(chuàng)建新的對(duì)象。如果沒(méi)有數(shù)據(jù)變化發(fā)生的話令花。

const { Map } = require('immutable')
const originalMap = Map({ a: 1, b: 2, c: 3 })
const updatedMap = originalMap.set('b', 2)
updatedMap === originalMap // return ture

如上代碼雖然進(jìn)行了一頓操作阻桅。然而數(shù)據(jù)并沒(méi)有改變。所以u(píng)pdatedMap和originalMap還是指向了同一個(gè)對(duì)象兼都。

const updatedMap = originalMap.set('b', 4)
updatedMap === originalMap
// return false

此時(shí)返回false

關(guān)于 React 的更新

import { is } from 'immutable';
shouldComponentUpdate: (nextProps, nextState) => {
  return !(this.props === nextProps || is(Map(this.props), Map(nextProps))) ||
         !(this.state === nextState || is(Map(this.state), Map(nextState)));
}

immutable 優(yōu)勢(shì)和使用場(chǎng)景

主要優(yōu)勢(shì):
1嫂沉、節(jié)省CPU
避免深拷貝,復(fù)雜對(duì)象比較
2扮碧、節(jié)省內(nèi)存
結(jié)構(gòu)共享趟章,復(fù)用已有結(jié)構(gòu)
3、lazy 操作


image.png

這段代碼的意思就是慎王,數(shù)組先取奇數(shù)蚓土,然后再對(duì)基數(shù)進(jìn)行平方操作,然后在console.log第2個(gè)數(shù)赖淤,同樣的代碼蜀漆,用immutable的seq對(duì)象來(lái)實(shí)現(xiàn),filter只執(zhí)行了3次咱旱,但原生執(zhí)行了8次确丢。??其實(shí)原理就是绷耍,用seq創(chuàng)建的對(duì)象,其實(shí)代碼塊沒(méi)有被執(zhí)行蠕嫁,只是被聲明了锨天,代碼在get(1)的時(shí)候才會(huì)實(shí)際被執(zhí)行,取到index=1的數(shù)之后剃毒,后面的就不會(huì)再執(zhí)行了病袄,所以在filter時(shí),第三次就取到了要的數(shù)赘阀,從4-8都不會(huì)再執(zhí)行??想想益缠,如果在實(shí)際業(yè)務(wù)中,數(shù)據(jù)量非常大基公,如在我們點(diǎn)餐業(yè)務(wù)中幅慌,商戶的菜單列表可能有幾百道菜,一個(gè)array的長(zhǎng)度是幾百轰豆,要操作這樣一個(gè)array胰伍,如果應(yīng)用惰性操作的特性,會(huì)節(jié)省非常多的性能
使用場(chǎng)景:
對(duì)于數(shù)據(jù)結(jié)構(gòu)復(fù)雜酸休,操作很多的使用immutable比較合適骂租。

優(yōu)勢(shì)

  • 不可變對(duì)象,降低了 Mutable 帶來(lái)的復(fù)雜度
foo={a: 1};
 bar=foo; 
bar.a=2
// foo.a 也變?yōu)榱?

雖然這樣做可以節(jié)約內(nèi)存斑司,但當(dāng)應(yīng)用復(fù)雜后渗饮,這就造成了非常大的隱患,Mutable 帶來(lái)的優(yōu)點(diǎn)變得得不償失宿刮。為了解決這個(gè)問(wèn)題互站,一般的做法是使用 shallowCopy(淺拷貝)或 deepCopy(深拷貝)來(lái)避免被修改,但這樣做造成了 CPU (額外的拷貝操作)和內(nèi)存(拷貝所需)的浪費(fèi)僵缺。
Immutable 特點(diǎn)是:持久化數(shù)據(jù)結(jié)構(gòu) && 結(jié)構(gòu)共享

  • 節(jié)省內(nèi)存
import { Map} from 'immutable';
let a = Map({
  select: 'users',
  filter: Map({ name: 'Cam' })
})
let b = a.set('select', 'people');

a === b; // false
a.get('filter') === b.get('filter'); // true
  • 用 cusor 訪問(wèn)嵌套較深的數(shù)據(jù)
import Immutable from 'immutable';
import Cursor from 'immutable/contrib/cursor';

let data = Immutable.fromJS({ a: { b: { c: 1 } } });
// 讓 cursor 指向 { c: 1 }
let cursor = Cursor.from(data, ['a', 'b'], newData => {
  // 當(dāng) cursor 或其子 cursor 執(zhí)行 update 時(shí)調(diào)用
  console.log(newData);
});

cursor.get('c'); // 1
cursor = cursor.update('c', x => x + 1);
cursor.get('c'); // 2

劣勢(shì)

  • 增加學(xué)習(xí)成本
  • 增加資源大小 immutable.js 壓縮后16K
  • 容易和原生對(duì)象混淆

React 相關(guān)

  • Immutable.is
    Immutable.is 比較的是兩個(gè)對(duì)象的 hashCode 或 valueOf(對(duì)于 JavaScript 對(duì)象)胡桃。由于 immutable 內(nèi)部使用了 Trie 數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ),只要兩個(gè)對(duì)象的 hashCode 相等磕潮,值就是一樣的标捺。這樣的算法避免了深度遍歷比較,性能非常好揉抵。

可使用 Immutable.is 來(lái)減少 React 重復(fù)渲染,提高性能嗤疯。當(dāng)傳遞基本數(shù)據(jù)類(lèi)型的屬性給子組件時(shí)冤今,子組件使用PureComponent即可;但是如果需要傳遞數(shù)組或?qū)ο蠼o子組件茂缚,這時(shí)就需要用到 Immutable,在子組件的shouldComponentUpdate中用Immutable.is 比較新舊對(duì)象從而減少無(wú)意義的渲染

參考文章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末戏罢,一起剝皮案震驚了整個(gè)濱河市屋谭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌龟糕,老刑警劉巖桐磁,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異讲岁,居然都是意外死亡我擂,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)缓艳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)校摩,“玉大人,你說(shuō)我怎么就攤上這事阶淘⊙梅裕” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵溪窒,是天一觀的道長(zhǎng)坤塞。 經(jīng)常有香客問(wèn)我,道長(zhǎng)澈蚌,這世上最難降的妖魔是什么摹芙? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮惜浅,結(jié)果婚禮上瘫辩,老公的妹妹穿的比我還像新娘。我一直安慰自己坛悉,他們只是感情好伐厌,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著裸影,像睡著了一般挣轨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上轩猩,一...
    開(kāi)封第一講書(shū)人閱讀 51,365評(píng)論 1 302
  • 那天卷扮,我揣著相機(jī)與錄音,去河邊找鬼均践。 笑死晤锹,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的彤委。 我是一名探鬼主播鞭铆,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼焦影!你這毒婦竟也來(lái)了车遂?” 一聲冷哼從身側(cè)響起封断,我...
    開(kāi)封第一講書(shū)人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎舶担,沒(méi)想到半個(gè)月后坡疼,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡衣陶,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年柄瑰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片祖搓。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡狱意,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出拯欧,到底是詐尸還是另有隱情详囤,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布镐作,位于F島的核電站藏姐,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏该贾。R本人自食惡果不足惜羔杨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望杨蛋。 院中可真熱鬧兜材,春花似錦、人聲如沸逞力。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)寇荧。三九已至举庶,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間揩抡,已是汗流浹背户侥。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留峦嗤,地道東北人蕊唐。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像烁设,于是被迫代替她去往敵國(guó)和親刃泌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 本篇只是對(duì)Immutable.js的簡(jiǎn)單介紹,后續(xù)會(huì)繼續(xù)分享其具體實(shí)踐應(yīng)用曹体。 什么是Immutable Data俗扇?...
    桂圓_noble閱讀 48,240評(píng)論 4 67
  • (一)Java部分 1、列舉出JAVA中6個(gè)比較常用的包【天威誠(chéng)信面試題】 【參考答案】 java.lang;ja...
    獨(dú)云閱讀 7,104評(píng)論 0 62
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法箕别,類(lèi)相關(guān)的語(yǔ)法铜幽,內(nèi)部類(lèi)的語(yǔ)法,繼承相關(guān)的語(yǔ)法串稀,異常的語(yǔ)法除抛,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 31,631評(píng)論 18 399
  • 一早醒來(lái)就遇到這么美的天空,心情能美一天母截。
    米心_f7fd閱讀 594評(píng)論 2 2
  • 終南山下到忽,活死人墓。神雕俠侶清寇,絕跡江湖喘漏。 自華山上與楊過(guò)小龍女分開(kāi)回到桃花島后,郭襄一直悵然若失华烟。 君生我未生翩迈,我...
    洛陽(yáng)風(fēng)輕閱讀 2,719評(píng)論 0 2