immutable深拷贝:数据多层属性-不可变数据结构

news/2025/3/20 22:23:31/

一、为何要用immutable深拷贝?

1.浅拷贝(浅复制)

//引用赋值-浅复制、浅拷贝

var obj={name:"溜溜球"}var obj2=obj;obj2.name="刘刘球";console.log(obj);//name:"刘刘球"console.log(obj2);//name:"刘刘球"

2.object.assign()一级属性复制,比浅复制多赋值一层,不是真正的深复制

//比浅复制多赋值一层,不是真正的深复制var myobj={name:"六六球",like:["打球","rapper"]}var myobj2={...myobj};myobj2.name="66球";myobj2.like.splice(0,1)console.log(myobj);console.log(myobj2);

3.const obj1 = JSON.parse(JSON.stringify(obj)); 数组,对象都好用的方法(缺点: 不能有undefined)

//json-parse json-stringify
var jsonobj={name:"遛遛",like:["下棋","swage"],
}
var jsonobj2=JSON.parse(JSON.stringify(jsonobj));
jsonobj2.name="66";
jsonobj2.like.splice(0,1);
console.log(jsonobj);
console.log(jsonobj2);

 有undefined时被丢弃

//json-parse json-stringify
var jsonobj={name:"遛遛",like:["下棋","swage"],age:undefined
}
var jsonobj2=JSON.parse(JSON.stringify(jsonobj));
jsonobj2.name="66";
jsonobj2.like.splice(0,1);
console.log(jsonobj);
console.log(jsonobj2);

Immutable 实现的原理是 Persistent Data Structure(持久化数据结构),也就是使用旧数据创建新数据时,要保证旧数据同时可用且不变。同时为了避免 deepCopy 把所有节点都复制一遍带来的性能损耗,Immutable 使用了 Structural Sharing(结构共享),即如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其它节点则进行共享 

二、使用

1.安装:npm install immutable

2.mmutable中常用类型(Map,List)

①Map(对象)

import React, { Component } from 'react';
import {Map} from 'immutable';
var obj={name:"六六",age:17
}
var oldImmuObj=Map(obj);
var newmmuObj=oldImmuObj.set( 'name',"66");
console.log(oldImmuObj,newmmuObj);
//1.get获取immutable
console.log(oldImmuObj.get('name'),newmmuObj.get('name'));
//2.immutable转为普通对象
console.log(oldImmuObj.toJS(),newmmuObj.toJS());

②List(数组)

import React, { Component } from 'react';
import { List } from 'immutable';var list=List([1,2,3]);
var list2=list.push([4,5]);
var list3=list.unshift(0);
console.log(list.toJS(),list2.toJS(),list3.toJS());
//push, set, unshift or splice 都可以直接用,返回一个新的immutable对象

 toJS():将复杂对象转为普通对象

const deep = Map({ a: 1, b: 2, c: List([ 3, 4, 5 ]) });
console.log(deep.toObject()); // { a: 1, b: 2, c: List [ 3, 4, 5 ] }
console.log(deep.toArray()); // [ 1, 2, List [ 3, 4, 5 ] ]
console.log(deep.toJS()); // { a: 1, b: 2, c: [ 3, 4, 5 ] }
JSON.stringify(deep); // '{"a":1,"b":2,"c":[3,4,5]}'

③.map与list案例

1.复杂案例

import React, { Component } from 'react';
import { List,Map } from 'immutable';class update extends Component {state={info:Map({name:"溜溜球",location:Map({provice:"四川",city:"成都"}),favor:List(["读书","看包","写代码"])})}render() {return (<div><button onClick={()=>{this.setState({info:this.state.info.set("name","66球").set("location",this.state.info.get("location").set("provice","广东").set("city","深圳"))})}}>修改</button><div>{this.state.info.get("name")}</div><div>{this.state.info.get("location").get("provice")}-{this.state.info.get("location").get("city",)}</div><div> <ol>{this.state.info.get("favor").map((item,index)=><li key={item}>{item}<button onClick={()=>{this.setState({info:this.state.info.set("favor",this.state.info.get("favor").splice(index,1))})}}>删除</button></li>   )}</ol></div></div>);}
}export default update;

 2.fromJS()方法将普通对象转为复杂对象,自动加上List和Map.提供了获取方法getIn(),设置新值方法setIn(),回调函数更新updateIn().


const nested = fromJS({ a: { b: { c: [ 3, 4, 5 ] } } });
// Map { a: Map { b: Map { c: List [ 3, 4, 5 ] } } }
const nested2 = nested.mergeDeep({ a: { b: { d: 6 } } });
// Map { a: Map { b: Map { c: List [ 3, 4, 5 ], d: 6 } } }
console.log(nested2.getIn([ 'a', 'b', 'd' ])); // 6
//如果取一级属性 直接通过get方法,如果取多级属性 getIn(["a","b","c"]])
//setIn 设置新的值
const nested3 = nested2.setIn([ 'a', 'b', 'd' ], "kerwin");
// Map { a: Map { b: Map { c: List [ 3, 4, 5 ], d: "kerwin" } } }
//updateIn 回调函数更新

const nested3 = nested2.updateIn([ 'a', 'b', 'd' ], value => value + 1);
console.log(nested3);
// Map { a: Map { b: Map { c: List [ 3, 4, 5 ], d: 7 } } }
const nested4 = nested3.updateIn([ 'a', 'b', 'c' ], list => list.push(6));
// Map { a: Map { b: Map { c: List [ 3, 4, 5, 6 ], d: 7 } } }

/** @Author: Spring* @LastEditors: Aidam_Bo* @LastEditTime: 2023-05-29 17:26:15*/
import React, { Component } from 'react';
import { fromJS} from 'immutable';class update extends Component {state={info:fromJS({name:"溜溜球",location:{provice:"四川",city:"成都"},favor:["读书","看包","写代码"]})}componentDidMount() {console.log("fromJS",this.state.info);}render() {return (<div><button onClick={()=>{this.setState({info:this.state.info.set("name","66球").setIn(["location","provice"],"广东").setIn(["location","city"],"深圳")})}}>修改</button><div>{this.state.info.get("name")}</div><div>{this.state.info.getIn(["location","provice"])}-{this.state.info.getIn(["location","city"])}</div><div> <ol>{this.state.info.get("favor").map((item,index)=><li key={item}>{item}<button onClick={()=>{this.setState({info:this.state.info.updateIn(["favor"],(list)=>list.splice(index,1))})}}>删除</button></li>   )}</ol></div></div>);}
}export default update;


http://www.ppmy.cn/news/103570.html

相关文章

物联网GPRS模块流量计算

物联网GPRS模块流量计算 MQTT(消息队列遥测传输) 是ISO 标准下一个基于TCP/IP的消息发布/订阅传输协议。 一、TCP消耗流量计算 以太网数据包结构&#xff1a; 以太网首部 IP首部 TCP首部 APPL首部 用户数据 以太网尾部 以太网首部为14个字节 IP首部为20个字节 TCP首部…

【Vue3】如何创建Vue3项目及组合式API

文章目录 前言 一、如何创建vue3项目&#xff1f; ①使用 vue-cli 创建 ②使用可视化ui创建 ③npm init vite-app ④npm init vuelatest 二、 API 风格 2.1 选项式 API (Options API) 2.2 组合式 API (Composition API) 总结 前言 例如&#xff1a;随着前端领域的不断发展&am…

Java工程师的工作内容以及需要掌握的技术要求

文章目录 1、Java工程师的基本要求包括 2、Java工程师需要掌握的技能包括 总结 1、Java工程师的基本要求包括 精通Java编程语言及相关技术熟悉常用的Java开发框架&#xff0c;如Spring、Hibernate等熟悉Web开发技术&#xff0c;如HTML、CSS、JavaScript等熟悉数据库开发技术…

JAVA——实验5 GUI类与问题域类的交互

一、实验目的 1.掌握Java中设计GUI界面的方法 2.掌握Java GUI界面上的事件监听机制 3.掌握GUI类与问题域交互的方法 二、实验内容 1. 设计Manager类、GUI类及事件处理 (1)设计一个Manager类并编写代码&#xff0c; Manager类的属性有姓名&#xff0c;工号&#xff0c;基本工…

凸缺陷 convexityDefects

获取凸包&#xff0c;可以参考我的这篇文章&#xff1a; 凸包&#xff08;Convex Hull&#xff09;代码实现案例 获取了凸包之后&#xff0c;可以干什么呢&#xff1f; 凸缺陷凸包与轮廓之间的部分称为凸缺陷。凸缺陷可用来处理手势识别等问题。 通常情况下&#xff0c;使用如…

【CSAPP】Binarybomb 实验(phase_1-6+secret_phase)

Binarybomb 实验&#xff08;phase_1-6secret_phase&#xff09; 实验内容 一个“binary bombs”&#xff08;二进制炸弹&#xff0c;下文将简称为炸弹&#xff09;是一个Linux可执行C程序&#xff0c;包含了7个阶段&#xff08;phase1~phase6和一个隐藏阶段&#xff09;。炸…

Autowired和Resource的区别

Autowired和Resource的区别 Resource和Autowired都是做bean的注入时使用&#xff0c;其实Resource并不是Spring的注解&#xff0c;它的包是javax.annotation.Resource&#xff0c;需要导入&#xff0c;但是Spring支持该注解的注入。 共同点 两者都可以写在字段和setter方法上…

用Spring Boot轻松实现定时任务--原理详解

用Spring Boot轻松实现定时任务 在现代化的web开发中&#xff0c;定时任务是一个非常常见的功能。Spring Boot为我们提供了一个简便的方式来处理这些任务&#xff0c;我们只需加入一些注解和配置即可完成。本文将介绍 Spring Boot 定时任务的基本概念和原理&#xff0c;以及如何…