国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

Immutable 在 JavaScript 中的應用

2019-11-20 10:10:42
字體:
供稿:網(wǎng)友

Mutable 對象
在 JavaScript 中,對象是引用類型的數(shù)據(jù),其優(yōu)點在于頻繁的修改對象時都是在原對象的基礎(chǔ)上修改,并不需要重新創(chuàng)建,這樣可以有效的利用內(nèi)存,不會造成內(nèi)存空間的浪費,對象的這種特性可以稱之為 Mutable,中文的字面意思是「可變」。
對于 Mutable 的對象,其靈活多變的優(yōu)點有時可能會成為其缺點,越是靈活多變的數(shù)據(jù)越是不好控制,對于一個復雜結(jié)構(gòu)的對象來說,一不小心就在某個不經(jīng)意間修改了數(shù)據(jù),假如該對象又在多個作用域中用到,此時很難預見到數(shù)據(jù)是否改變以及何時改變的。

var obj = { /* 一個復雜結(jié)構(gòu)的對象 */ };doSomething(obj);// 上面的函數(shù)之行完后,此時的 obj 還是最初的那個 obj 嗎?

針對這種問題,常規(guī)的解決辦法可以通過將對象進行深拷貝的形式復制出一個新的對象,再在新對象上做修改的操作,這樣能確保數(shù)據(jù)的可控性,但是頻繁的復制會造成內(nèi)存空間的大量浪費。

var obj = { /* 一個復雜結(jié)構(gòu)的對象 */ };// copy 出一個新的 obj2// 但是 copy 操作會浪費內(nèi)存空間var obj2 = deepClone(obj);doSomething(obj2);// 上面的函數(shù)之行完后,無論 obj2 是否變化,obj 肯定還是原來那個 obj

Immutable 對象
為了能更好的解決上述的問題,出現(xiàn)了 Immutable 對象,Immutable 從字面上翻譯成中文是「不可變」。每次修改一個 Immutable 對象時都會創(chuàng)建一個新的不可變的對象,在新對象上操作并不會影響到原對象的數(shù)據(jù)。這種特殊的對象并不是 JavaScript 新出的功能特性,而是業(yè)界為了解決這種問題提供的一套解決方案,并且涌現(xiàn)出了一些優(yōu)秀的開源類庫,其中最有名的就是 Facebook 的 Lee Byron 開源的 immutable.js。當然,Immutable 的這種解決方案并不是獨創(chuàng)的,而是來源于 Clojure 和 Scala。
Mutable 和 Immutable 的性能對比
對于 Mutable 的對象的低效率操作主要體現(xiàn)在復制和比較上,而 Immutable 對象就是解決了這兩大低效的痛點。
普通的 Mutable 對象的深拷貝操作會將一整份數(shù)據(jù)都復制一遍,而 Immutable 對象在修改數(shù)據(jù)時并不會復制一整份數(shù)據(jù),而是將變化的節(jié)點與未變化的節(jié)點的父子關(guān)系轉(zhuǎn)移到一個新節(jié)點上,類似于鏈表的結(jié)構(gòu)。從 “復制” 的角度來看,做到了最小化的復制,未變化的部分都是共享的,Mutable 在復制的時候是 “全量”,而 Immutable 復制的是 “增量”,對于內(nèi)存空間的使用率的比較高低立判。
并且基于每次修改一個 Immutable 對象都會創(chuàng)建一個新的 Immutable 對象的這種特性可以將數(shù)據(jù)的修改狀態(tài)保存成一組快照,這也是挺方便的。
再來說說比較操作。對于 Mutable 的對象,如果要比較兩個對象是否相等,必須遍歷對象的每個節(jié)點進行比較,對于結(jié)構(gòu)復雜的對象來說,其效率肯定高不到哪去。對于 Immutable 對象,immutable.js 提供了直接判斷兩個 Immutable 對象的「值」是否相等的 API。

var map1 = Immutable.Map({a:1, b:1, c:1});var map2 = Immutable.Map({a:1, b:1, c:1});assert(map1 !== map2); // 不同的 Immutable 實例,此時比較的是引用地址assert(Immutable.is(map1, map2)); // map1 和 map2 的值相等,比較的是值assert(map1.equals(map2)); // 與 Immutable.is 的作用一樣

在實際的開發(fā)應用中,性能并不總是最關(guān)鍵和重要的,對于普通的 JavaScript 的項目來說,由于 Immutable 的特性帶來的數(shù)據(jù)的可控性比起性能來說更有優(yōu)勢,對于 Mutable 對象適合在封閉的作用域小范圍使用,而 Immutable 對象適合數(shù)據(jù)需要跨多個作用域傳遞時使用。

Mutable 和 Immutable 在使用上的區(qū)別

immutable.js 提供了多種 Immutable 的數(shù)據(jù)結(jié)構(gòu):包含了 List Stack Map OrderedMap Set OrderedSet Record,這些數(shù)據(jù)結(jié)構(gòu)與原生的 Mutable 的數(shù)據(jù)結(jié)構(gòu)大致對應。
各數(shù)據(jù)結(jié)構(gòu)的用法這里不細說,主要說說 Immutable 對象與 Mutable 對象在使用上的區(qū)別吧。
原生的 Mutable 對象在「讀」和「寫」上非常方便。

var mutableObj = {};// 寫入數(shù)據(jù)mutableObj.foo = 'bar';// 讀取數(shù)據(jù)console.log(mutableObj.foo);

而 Immutable 對象需要通過 set 和 get 來對數(shù)據(jù)進行「讀」和「寫」。

var immutableObj1 = Immutable.Map();// 寫入數(shù)據(jù)var immutableObj2 = immutableObj1.set('foo', 'bar');// 讀取數(shù)據(jù)console.log(immutableObj2.get('foo')); // => 'bar'

上面的例子為了說明 set 方法的使用才在一開始創(chuàng)建了一個空對象,實際上可以在實例化的時候傳初始值。

var immutableObj = Immutable.Map({'foo', 'bar'});

對于層級比較深的數(shù)據(jù),immutable.js 提供的訪問接口很方便。

var immutableObj1 = Immutable.fromJS({ a: {  b: 'c' }, d: [1, 2, 3]});// 讀取深層級的數(shù)據(jù)console.log(immutableObj1.getIn(['a', 'b'])); // => 'c'console.log(immutableObj1.getIn(['d', 1])); // => 2// 修改深層級的數(shù)據(jù)var immutableObj2 = immutableObj1.setIn(['a', 'b'], 'd');console.log(immutableObj2.getIn(['a', 'b'])); // => 'd'

如果是原生的 Mutable 對象,在鏈式訪問一個深層級的數(shù)據(jù)時可能會報對象 undefined 的錯誤,而 Immutable 對象在碰到這種情況時不會報錯,返回的是 undefined。
在調(diào)試的時候,如果想查看一個 Immutable 對象的內(nèi)部結(jié)構(gòu),建議使用 toJSON() 先轉(zhuǎn)換為普通的 Mutable 對象。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 宜阳县| 海安县| 依兰县| 江孜县| 扶沟县| 平顶山市| 大埔县| 梅河口市| 方山县| 洛浦县| 邯郸县| 禄丰县| 阿瓦提县| 罗甸县| 龙里县| 宣城市| 交城县| 安龙县| 周口市| 天气| 湘阴县| 古交市| 赤水市| 资兴市| 新乐市| 永安市| 永修县| 越西县| 维西| 河曲县| 多伦县| 甘谷县| 宜宾市| 仪征市| 美姑县| 峡江县| 龙胜| 钟祥市| 海门市| 谢通门县| 洛阳市|