Proxy的不可变数据优点及使用方法是什么
这篇文章主要介绍“Proxy的不可变数据优点及使用方法是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Proxy的不可变数据优点及使用方法是什么”文章能帮助大家解决问题。
可变数据
对象被赋值后,更改对象,两个都会改变,因为其引用着相同的地址,我们称这为可变对象
所以这会造成意想不到的修改
React 要求本地组件的状态保持不可变性,Redux 同样要求全局状态保持不可变
不可变数据(Immutable Data)
Immutable.js 中 对 Immutable 对象 增删改查都会返回一个全新的 Immutable 对象,保证旧数据的可用不变
Immutable 使用了结构共享,即对象树中的节点改变只会影响自己和其父节点,其他节点共享
优点
保护数据意外更改,减少bug
方便跟踪数据变更,便于排错
实现一:独立方法
调用麻烦
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: '云牧' }
实现二:自定义对象
自定义新的对象类型,对其操作细节封装在其内部
著名的
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: '云牧' } }
实现三:函数 + 复制
函数调用产生新对象,对其新对象操作之后返回
性能损耗比较大
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: '云牧' }
实现四:Proxy代理
function produce(obj, recipe) { const state = { base: obj, // 基础对象 copy: {}, // 被更改后的对象 draft: {}, // 代理对象 currentKey: 0 // 当前操作的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
实现五:第三方不可变对象
JS没有不可变结构,我们一般可以使用
Immutable.js
和immerjs
Immutable.js
需要学习他的数据格式操作,且其不可变数据需要toJS
才能得到原生对象,心智负担大immerjs
则没有这方面的问题,且体积更为小巧
关于“Proxy的不可变数据优点及使用方法是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网行业资讯频道,小编每天都会为大家更新不同的知识点。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341