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

一、为何要用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;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/24043.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

解说天下之操作系统

解说天下之操作系统 本文由桌案drawon (https://www.drawon.cn)&#xff0c;云晶&#xff08;https://www.yunjingxz.com&#xff09;创始人根据多年从业经验&#xff0c; 从操作系统的起源&#xff0c;应用分类&#xff0c; 设计分类&#xff0c;以及资源使用角度对操作系统进…

2023年6月18日DAMA-CDGA/CDGP认证北京/上海/深圳报名

DAMA认证为数据管理专业人士提供职业目标晋升规划&#xff0c;彰显了职业发展里程碑及发展阶梯定义&#xff0c;帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力&#xff0c;促进开展工作实践应用及实际问题解决&#xff0c;形成企业所需的新数字经济下的核心职业…

思维导图到底有多少种?

思维导图是一种非常实用的工具&#xff0c;它可以帮助我们更好地组织和表达我们的思想。在日常生活和工作中&#xff0c;我们可以使用各种不同类型的思维导图来解决不同的问题。下面&#xff0c;我将介绍一些常见的思维导图类型以及如何使用ProcessOn思维导图软件制作思维导图。…

ThreadLocal的应用

1. ThreadLocal 是什么 JDK 对ThreadLocal的描述为&#xff1a; 此类提供线程局部变量。这些变量与普通变量的不同之处在于&#xff0c;每个访问一个变量的线程&#xff08;通过其get或set方法&#xff09;都有自己的、独立初始化的变量副本。ThreadLocal 实例通常是类中的私有…

Centos7安装Java8(在线安装避坑详细安装)

开篇语&#xff1a; 喜欢在一个明媚阳光的午后 坐在那夕阳斑驳的南墙下 听着风起 闻着花香 望着远山 身边是你 如此便觉得很好 1.查看目前环境 rpm -qa|grep jdk在这里我们会发现&#xff0c;原有系统安装有jdk&#xff0c;如果对于jdk有要求&#xff0c;我们就需要重新安装jdk…

面了一个测试工程师要求月薪26K,总感觉他背了很多面试题...

最近有朋友去字节面试&#xff0c;面试前后进行了20天左右&#xff0c;包含4轮电话面试、1轮笔试、1轮主管视频面试、1轮hr视频面试。 据他所说&#xff0c;80%的人都会栽在第一轮面试&#xff0c;要不是他面试前做足准备&#xff0c;估计都坚持不完后面几轮面试。 其实&…

3DMAX车缝线生成器插件使用方法详解

3dMax车缝线生成器插件,用于创建缝合对象和一个对象,以沿样条线或仅通过绘制选定边上的缝合之间的孔。 目前有两种类型的缝线,圆形缝线和平面缝线。对于给定类型的针脚,它们的厚度是最常用的。缝线的长度和间距以及旋转都可以很容易地调整,这些参数也可以随机设置,以创造…

[C语言][典例详解]打印杨辉三角(找规律简单实现)

目录 杨辉三角的相关知识 杨辉三角图&#xff1a; 杨辉三角的规律 在编程中实现 第一步 &#xff1a;我们先实现数字的打印&#xff0c;后面再加上空格构成三角形形状&#xff1b; ​编辑 1.首先我们可以直观的看出三角形的两个斜边都是1&#xff1b;所以我们先打印斜边的…

Python自动化测试框架有哪些?怎么选

目录 自动化测试框架概念 自动化测试框架根据思想理念和深度不同&#xff0c;渐进式的分为以下几种&#xff1a; 模块化测试脚本框架&#xff1a; 测试库框架&#xff1a; 数据驱动测试框架&#xff1a; 关键字驱动或表驱动的测试框架&#xff1a; 混合测试自动化框架&am…

沉浸式翻译 安装及使用

介绍一下最近非常或的沉浸式翻译工具&#xff0c;非常有助于外文阅读&#xff0c;包括网页、pdf等。可以同时显示原文和译文&#xff0c;操作简单&#xff0c;使用起来还是非常友好的。 先上链接&#xff1a;介绍 - 沉浸式翻译 如何使用 - 沉浸式翻译 1.安装 支持Edg…

Linux——使用命令行参数管理环境变量

目录 使用命令行参数获取用户在DOS命令行输入的指令&#xff1a; 方法&#xff1a;代码如下&#xff1a; 使用命令行参数获取并打印部分或者整体环境变量的方法&#xff1a; 方法1&#xff1a; 运行结果&#xff1a; 方法2&#xff1a;使用外部链接environ: 使用命令行参数…

article-并联机械手爪运动学分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3aNKIR4E-1685371700448)(data:image/svgxml;utf8, )] 2.4.3 基于Robotics Toolbox的工具箱的模型检测 上文中&#xff0c;我们已经对采摘机器手爪运动学理论模型进行了创建&#xff0c;接下来要用MA…

【智慧排水】智慧排水监测系统助力城市抗洪排涝建设

随着城市的发展和生活水平的提高&#xff0c;城市排水系统面临着各种挑战和难题。虽然国家已经大力建设和改造雨污分流系统&#xff0c;以解决城市排水问题&#xff0c;但在实际应用中仍然存在着诸多难题&#xff0c;如雨污混接、偷排漏排、管道堵塞淤积、管道溢流和内涝等问题…

没有经验能做产品经理吗?

没有经验能做产品经理吗&#xff1f;这是一个经常被讨论的问题&#xff0c;因为很多人想转行成为产品经理&#xff0c;但他们没有相关的工作经验。这里我也给出一些解答。 一、产品经理的职责和技能 首先&#xff0c;让我们看一下产品经理的职责和技能。产品经理是负责产品开…

java项目打包方式

普通项目打包 项目内容很简单&#xff0c;只是引用了一个三方包。 打包步骤 File-Project Structure... 点击确定后选择Build - Build Artifacts.. 选择build即可&#xff0c;可以查看编译日志 maven项目打包 若果是普通项目就先转为maven项目。 右键项目选择第二项add frame…

SpringCloud Nacos实战应用

目录 1 Nacos安装1.1 Nacos概要1.2 Nacos架构1.3 Nacos安装1.3.1 Nacos Derby安装1.3.2 Nacos MySQL版安装1.3.3 Docker 安装Nacos 2 Nacos功能应用2.1 Nacos服务注册与发现2.2 负载均衡2.3 配置中心2.4 灰度发布 3 Nacos集群3.1 集群架构3.2 Nacos集群部署3.3 客户端接入Nacos…

华为OD机试之打印机队列(Java源码)

打印机队列 题目描述 有5台打印机打印文件&#xff0c;每台打印机有自己的待打印队列。 因为打印的文件内容有轻重缓急之分&#xff0c;所以队列中的文件有1~10不同的代先级&#xff0c;其中 数字越大优先级越高 打印机会从自己的待打印队列中选择优先级最高的文件来打印。 如…

Windows 上安装和启动 Nacos 2.2.2 最新版本

文章目录 前言版本声明本地启动1. 下载 Nacos2. 开启鉴权配置3. 持久化数据库4. 启动 Nacos5. 启动测试 联系我 前言 本文旨在为您详细介绍如何安装和启动 Nacos 2.2.2 的最新版本&#xff0c;以及为 youlai-mall 开源商城版本的升级做好准备工作。 版本声明 名称版本操作系…

3年外包裸辞,面试阿里、字节全都一面挂,哭死.....

测试员可以先在外包积累经验&#xff0c;以后去大厂就很容易&#xff0c;基本不会被卡&#xff0c;事实果真如此吗&#xff1f;但是在我身上却是给了我很大一巴掌... 所谓今年今天履历只是不卡简历而已&#xff0c;如果面试答得稀烂&#xff0c;人家根本不会要你。况且要不是大…

c#快速入门

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;题目大解析2 目录 &#x1f449;&#x1f3fb; c#和c不同之处&#x1f449;&#x1f3fb;程序文件的…