[Javascript] 數據處理: Immer.js

Immer.js
https://github.com/mweststrate/immer

怎麼評價 immer.js?
https://www.zhihu.com/question/266511546

精讀《Immer.js》源碼
https://juejin.im/post/5aaf6d596fb9a028d207be00

immer.js 簡介及源碼解析
https://segmentfault.com/a/1190000013088373

處理 JavaScript 複雜物件:深拷貝、Immutable & Immer
https://juejin.im/post/5bbad07ce51d450e894e4228

我們知道 js 物件是按共用傳遞(call by sharing)的,因此在處理複雜 js 物件的時候,往往會因為修改了物件而產生副作用———因為不知道誰還引用著這份資料,不知道這些修改會影響到誰。因此我們經常會把物件做一次拷貝再放到處理函式中。但如果需要頻繁地操作一個複雜物件,每次都完全深拷貝一次的話效率太低了。大部分場景下都只是更新了這個物件一兩個欄位,其他的欄位都不變,對這些不變的欄位的拷貝明顯是多餘的。

這些庫的關鍵思路即是:創建持久化的資料結構(Persistent data structure),在操作物件的時候只 clone 變化的節點和其祖先節點,其他的保持不變,實現結構共用(structural sharing),也就是使用舊資料創建新資料時,要保證舊資料同時可用且不變,也能避免 deepCopy 把所有節點都複製一遍帶來的性能損耗。

不可變資料類型是源於函數式程式設計中的,是一條必備的準則。函數式對資料處理的時候,通過把問題抽象成一個個的純函數,每個純函數的操作都會返回新的資料類型,都不會影響之前的資料,保證了變數/參數的不可變性,增加代碼可讀性。

縱觀 Immer.js 的實現,核心的原理就是放在了對物件讀寫的劫持,從表現形式上立刻就能讓人想到 vue、mobx 從核心原理上來說也是對物件的讀寫劫持,現在很多框架也喜歡這麼搞,用 Object.defineProperty 達到效果。而 Immer.js 是用的 Proxy 實現的,也就是對原始資料中每個訪問到的節點都創建一個 Proxy,修改節點時修改副本而不操作原資料,最後返回到物件由未修改的部分和已修改的副本組成。


#Immer.js, Javascript, Persistent Data Structure, Structural Sharing, DeepCopy, 持久化資料結構

留言