Proxy的不可變數(shù)據(jù)優(yōu)點及使用詳解
更新時間:2023年03月02日 09:21:16 作者:云牧
這篇文章主要為大家介紹了Proxy的不可變數(shù)據(jù)優(yōu)點及使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
可變數(shù)據(jù)
- 對象被賦值后,更改對象,兩個都會改變,因為其引用著相同的地址,我們稱這為可變對象
- 所以這會造成意想不到的修改
- React 要求本地組件的狀態(tài)保持不可變性,Redux 同樣要求全局狀態(tài)保持不可變
不可變數(shù)據(jù)(Immutable Data)
- Immutable.js 中 對 Immutable 對象 增刪改查都會返回一個全新的 Immutable 對象,保證舊數(shù)據(jù)的可用不變
- Immutable 使用了結(jié)構(gòu)共享,即對象樹中的節(jié)點改變只會影響自己和其父節(jié)點,其他節(jié)點共享
優(yōu)點
- 保護數(shù)據(jù)意外更改,減少bug
- 方便跟蹤數(shù)據(jù)變更,便于排錯
實現(xiàn)一:獨立方法
- 調(diào)用麻煩
function updateData(obj, key, value) { return { ...obj, [key]: value }; } const obj = { name: "云牧" }; const newObj = updateData(obj, "name", "黛玉"); console.log(newObj); // { name: '黛玉' } console.log(obj); // { name: '云牧' }
實現(xiàn)二:自定義對象
- 自定義新的對象類型,對其操作細節(jié)封裝在其內(nèi)部
- 著名的
immutable-js
,就是這個思路,定義了List
、Stack
、Map
、OrderedMap
、Set
、OrderedSet
和Record
這么多對象
class MyObject { constructor(obj = {}) { this.obj = { ...obj }; } get(name) { return this.obj[name]; } set(name, value) { return new MyObject({ ...this.obj, [name]: value }); } } const obj = new MyObject({ name: "云牧" }); const newObj = obj.set("name", "黛玉"); console.log(newObj); // MyObject { obj: { name: '黛玉' } } console.log(obj); // MyObject { obj: { name: '云牧' } }
實現(xiàn)三:函數(shù) + 復(fù)制
- 函數(shù)調(diào)用產(chǎn)生新對象,對其新對象操作之后返回
- 性能損耗比較大
function produce(obj, recipe) { const newObj = { ...obj }; recipe(newObj); return newObj; } const obj = { name: "云牧" }; const newObj = produce(obj, draft => { draft.name = "黛玉"; }); console.log(newObj); // { name: '黛玉' } console.log(obj); // { name: '云牧' }
實現(xiàn)四:Proxy代理
function produce(obj, recipe) { const state = { base: obj, // 基礎(chǔ)對象 copy: {}, // 被更改后的對象 draft: {}, // 代理對象 currentKey: 0 // 當(dāng)前操作的key }; const handlerItem = { get(target, property, receiver) { // 如果更改后的對象存在則使用copy if (state.copy[state.currentKey]) { return state.copy[state.currentKey][property]; } return state.base[state.currentKey][property]; }, set(target, property, value, receiver) { Reflect.set(state.copy[state.currentKey], property, value); } }; const handler = { get(target, property, receiver) { state.currentKey = property; if (!state.draft[property]) { const val = { ...state.base[property] }; const proxy = new Proxy(val, handlerItem); state.draft[property] = proxy; state.copy[property] = val; } return state.draft[property]; }, set(target, property, value, receiver) { return Reflect.set(state.copy, property, value); } }; const proxyObj = new Proxy(obj, handler); recipe(proxyObj); return proxyObj; } const arrObj = Array.from({ length: 100 }, (v, index) => ({ name: "云牧" + index })); const newObj = produce(arrObj, draft => { draft[50].name = "黛玉"; }); console.log(newObj[50].name); // 黛玉 console.log(arrObj[50].name); // 云牧50
實現(xiàn)五:第三方不可變對象
- JS沒有不可變結(jié)構(gòu),我們一般可以使用
Immutable.js
和immerjs
Immutable.js
需要學(xué)習(xí)他的數(shù)據(jù)格式操作,且其不可變數(shù)據(jù)需要toJS
才能得到原生對象,心智負擔(dān)大immerjs
則沒有這方面的問題,且體積更為小巧
以上就是Proxy的不可變數(shù)據(jù)優(yōu)點及使用詳解的詳細內(nèi)容,更多關(guān)于Proxy不可變數(shù)據(jù)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
微信小程序 免費SSL證書https、TLS版本問題的解決辦法
這篇文章主要介紹了微信小程序 免費SSL證書https、TLS版本問題的解決辦法的相關(guān)資料,需要的朋友可以參考下2016-12-12在微信小程序中渲染HTML內(nèi)容3種解決方案及分析與問題解決
在開發(fā)微信小程序時我們會在小程序內(nèi)加入純HTML代碼,且HTML中包括圖片,視頻,甚至是事件,微信小程序為我們提供了3種解決方法,但它們的功能與實現(xiàn)方式與最終效果并不理想2020-01-01Proxy Facade設(shè)計模式簡化系統(tǒng)訪問的強大工具原理詳解
這篇文章主要為大家介紹了 Proxy Facade設(shè)計模式簡化系統(tǒng)訪問的強大工具原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-10-10TypeScript新語法之infer?extends示例詳解
這篇文章主要為大家介紹了TypeScript新語法之infer?extends示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-08-08