Proxy的不可變數(shù)據(jù)優(yōu)點(diǎn)及使用詳解
可變數(shù)據(jù)
- 對(duì)象被賦值后,更改對(duì)象,兩個(gè)都會(huì)改變,因?yàn)槠湟弥嗤牡刂?,我們稱這為可變對(duì)象
- 所以這會(huì)造成意想不到的修改
- React 要求本地組件的狀態(tài)保持不可變性,Redux 同樣要求全局狀態(tài)保持不可變
不可變數(shù)據(jù)(Immutable Data)
- Immutable.js 中 對(duì) Immutable 對(duì)象 增刪改查都會(huì)返回一個(gè)全新的 Immutable 對(duì)象,保證舊數(shù)據(jù)的可用不變
- Immutable 使用了結(jié)構(gòu)共享,即對(duì)象樹(shù)中的節(jié)點(diǎn)改變只會(huì)影響自己和其父節(jié)點(diǎn),其他節(jié)點(diǎn)共享
優(yōu)點(diǎn)
- 保護(hù)數(shù)據(jù)意外更改,減少bug
- 方便跟蹤數(shù)據(jù)變更,便于排錯(cuò)
實(shí)現(xiàn)一:獨(dú)立方法
- 調(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: '云牧' }
實(shí)現(xiàn)二:自定義對(duì)象
- 自定義新的對(duì)象類(lèi)型,對(duì)其操作細(xì)節(jié)封裝在其內(nèi)部
- 著名的
immutable-js,就是這個(gè)思路,定義了List、Stack、Map、OrderedMap、Set、OrderedSet和Record這么多對(duì)象
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: '云牧' } }
實(shí)現(xiàn)三:函數(shù) + 復(fù)制
- 函數(shù)調(diào)用產(chǎn)生新對(duì)象,對(duì)其新對(duì)象操作之后返回
- 性能損耗比較大
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: '云牧' }
實(shí)現(xiàn)四:Proxy代理
function produce(obj, recipe) {
const state = {
base: obj, // 基礎(chǔ)對(duì)象
copy: {}, // 被更改后的對(duì)象
draft: {}, // 代理對(duì)象
currentKey: 0 // 當(dāng)前操作的key
};
const handlerItem = {
get(target, property, receiver) {
// 如果更改后的對(duì)象存在則使用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
實(shí)現(xiàn)五:第三方不可變對(duì)象
- JS沒(méi)有不可變結(jié)構(gòu),我們一般可以使用
Immutable.js和immerjs Immutable.js需要學(xué)習(xí)他的數(shù)據(jù)格式操作,且其不可變數(shù)據(jù)需要toJS才能得到原生對(duì)象,心智負(fù)擔(dān)大immerjs則沒(méi)有這方面的問(wèn)題,且體積更為小巧
以上就是Proxy的不可變數(shù)據(jù)優(yōu)點(diǎn)及使用詳解的詳細(xì)內(nèi)容,更多關(guān)于Proxy不可變數(shù)據(jù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
微信小程序 免費(fèi)SSL證書(shū)https、TLS版本問(wèn)題的解決辦法
這篇文章主要介紹了微信小程序 免費(fèi)SSL證書(shū)https、TLS版本問(wèn)題的解決辦法的相關(guān)資料,需要的朋友可以參考下2016-12-12
在微信小程序中渲染HTML內(nèi)容3種解決方案及分析與問(wèn)題解決
在開(kāi)發(fā)微信小程序時(shí)我們會(huì)在小程序內(nèi)加入純HTML代碼,且HTML中包括圖片,視頻,甚至是事件,微信小程序?yàn)槲覀兲峁┝?種解決方法,但它們的功能與實(shí)現(xiàn)方式與最終效果并不理想2020-01-01
JavaScript中的設(shè)計(jì)模式 單例模式
這篇文章主要給大家介紹的是JavaScript中的單例模式,設(shè)計(jì)模式代表了最佳的實(shí)踐,通常被有經(jīng)驗(yàn)的面向?qū)ο蟮能浖_(kāi)發(fā)人員所采用。設(shè)計(jì)模式是軟件開(kāi)發(fā)人員在軟件開(kāi)發(fā)過(guò)程中面臨的一般問(wèn)題的解決方案,需要的朋友可以參考一下2021-09-09
Proxy Facade設(shè)計(jì)模式簡(jiǎn)化系統(tǒng)訪問(wèn)的強(qiáng)大工具原理詳解
這篇文章主要為大家介紹了 Proxy Facade設(shè)計(jì)模式簡(jiǎn)化系統(tǒng)訪問(wèn)的強(qiáng)大工具原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10
TypeScript順時(shí)針打印矩陣實(shí)現(xiàn)實(shí)例詳解
這篇文章主要為大家介紹了TypeScript順時(shí)針打印矩陣實(shí)現(xiàn)實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
TypeScript新語(yǔ)法之infer?extends示例詳解
這篇文章主要為大家介紹了TypeScript新語(yǔ)法之infer?extends示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08

