Immutable 在 JavaScript 的應用_javascript技巧
Mutable 物件
在JavaScript 中,物件是引用類型的數據,其優點在於頻繁的修改對象時都是在原對象的基礎上修改,並不需要重新創建,這樣可以有效的利用內存,不會造成內存空間的浪費,對象的這種特性可以稱為Mutable,中文的字面意思是「可變」。
對於Mutable 的對象,其靈活多變的優點有時可能會成為其缺點,越是靈活多變的資料越是不好控制,對於一個複雜結構的對象來說,一不小心就在某個不經意間修改了數據,假如該物件又在多個作用域中用到,此時很難預見數據是否改變以及何時改變的。
var obj = { /* 一个复杂结构的对象 */ }; doSomething(obj); // 上面的函数之行完后,此时的 obj 还是最初的那个 obj 吗?
針對這種問題,常規的解決方法可以透過將對象進行深拷貝的形式複製出一個新的對象,再在新對像上做修改的操作,這樣能確保數據的可控性,但是頻繁的複製會造成記憶體空間的大量浪費。
var obj = { /* 一个复杂结构的对象 */ }; // copy 出一个新的 obj2 // 但是 copy 操作会浪费内存空间 var obj2 = deepClone(obj); doSomething(obj2); // 上面的函数之行完后,无论 obj2 是否变化,obj 肯定还是原来那个 obj
Immutable 物件
為了能更好的解決上述的問題,出現了 Immutable 對象,Immutable 從字面上翻譯成中文是「不可變」。每次修改一個 Immutable 物件時都會建立一個新的不可變的對象,在新物件上操作並不會影響到原對象的資料。這個特殊的物件並不是JavaScript 新出的功能特性,而是業界為了解決這種問題所提供的一套解決方案,並且湧現出了一些優秀的開源類別庫,其中最有名的就是Facebook 的Lee Byron 開源的immutable.js。當然,Immutable 的這種解決方案並不是獨創的,而是來自於 Clojure 和 Scala。
Mutable 和 Immutable 的效能比較
對於 Mutable 的物件的低效率操作主要體現在複製和比較上,而 Immutable 物件就是解決了這兩大低效的痛點。
普通的Mutable 物件的深拷貝操作會將一整份資料都複製一遍,而Immutable 物件在修改資料時並不會複製一整份數據,而是將變化的節點與未變更的節點的父子關係轉移到一個新節點上,類似鍊錶的結構。從“複製” 的角度來看,做到了最小化的複製,未變化的部分都是共享的,Mutable 在複製的時候是“全量”,而Immutable 複製的是“增量”,對於內存空間的使用率的比較高低立判。
並且基於每次修改一個 Immutable 物件都會建立一個新的 Immutable 物件的這種特性可以將資料的修改狀態保存成一組快照,這也是挺方便的。
再來說說比較操作。對於 Mutable 的對象,如果要比較兩個物件是否相等,必須遍歷物件的每個節點進行比較,對於結構複雜的物件來說,其效率肯定高不到哪裡去。對於 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 的作用一样
在實際的開發應用中,效能並不總是最關鍵和重要的,對於普通的JavaScript 的專案來說,由於Immutable 的特性帶來的資料的可控性比起效能來說更有優勢,對於Mutable 物件適合在封閉的作用域小範圍使用,而Immutable 物件適合資料需要跨多個作用域傳遞時使用。
Mutable 和 Immutable 在使用上的差異
immutable.js 提供了多種 Immutable 的資料結構:包含了 List Stack Map OrderedMap Set OrderedSet Record,這些資料結構與原生的 Mutable 的資料結構大致對應。
各資料結構的用法這裡不細說,主要說說 Immutable 物件與 Mutable 物件在使用上的差異。
原生的 Mutable 物件在「讀取」和「寫」上非常方便。
var mutableObj = {}; // 写入数据 mutableObj.foo = 'bar'; // 读取数据 console.log(mutableObj.foo);
而 Immutable 物件需要透過 set 和 get 來對資料進行「讀取」和「寫入」。
var immutableObj1 = Immutable.Map(); // 写入数据 var immutableObj2 = immutableObj1.set('foo', 'bar'); // 读取数据 console.log(immutableObj2.get('foo')); // => 'bar'
上面的例子為了說明 set 方法的使用才在一開始創建了一個空對象,實際上可以在實例化的時候傳初始值。
var immutableObj = Immutable.Map({'foo', 'bar'});
對於層級比較深的數據,immutable.js 提供的存取介面很方便。
var immutableObj1 = Immutable.fromJS({ a: { b: 'c' }, d: [1, 2, 3] }); // 读取深层级的数据 console.log(immutableObj1.getIn(['a', 'b'])); // => 'c' console.log(immutableObj1.getIn(['d', 1])); // => 2 // 修改深层级的数据 var immutableObj2 = immutableObj1.setIn(['a', 'b'], 'd'); console.log(immutableObj2.getIn(['a', 'b'])); // => 'd'
如果是原生的 Mutable 對象,在鍊式存取一個深層的資料時可能會報物件 undefined 的錯誤,而 Immutable 物件在碰到這種情況時不會報錯,回傳的是 undefined。
在調試的時候,如果想查看一個 Immutable 物件的內部結構,建議使用 toJSON() 先轉換為普通的 Mutable 物件。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

IMX 交易於關鍵阻力區域,該阻力區域既是斐波那契回檔位,也是看跌訂單區域。比特幣 (BTC) 價格從 6.42 萬美元暴跌至 5.82 萬美元,IMX 價格下跌了 13%。

在本週的通訊中,了解 Immutable 為何退出其不可替代代幣 (NFT) 市場,以及為何 Kanpai Pandas NFT 底價在團隊參與唐納德·特朗普主題代幣後下降。看看為什麼一位高階主管相信 W

以太坊的第二層擴容解決方案IMX價格在過去一個月呈現看漲趨勢,上漲了31%。儘管有所增加,但由於最近的市場調整,IMX 的價格目前顯示出波動的跡象。

山寨幣市場正在波動,但一些代幣試圖反彈。在此盤整階段,投資人需要保持警惕,因為這可能是乘勢上升趨勢的機會。

美國證券交易委員會已瞄準區塊鏈遊戲平台 Immutable,該平台可能會在 2021 年上市並私募銷售 IMX 代幣。

Immutable 已表示打算挑戰 SEC 的主張,認為該主張的重點是 2021 年其原生 IMX 代幣的上市和私人銷售。

Immutable 是區塊鏈遊戲和不可替代代幣 (NFT) 領域著名的第 2 層網絡,該網絡已宣布關閉其 NFT 市場。

區塊鏈遊戲平台 Immutable 收到了美國證券交易委員會 (SEC) 的 Wells 通知,表明可能對涉嫌證券違規行為採取執法行動。
