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

news2024/10/1 17:42:11

一、为何要用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.coloradmin.cn/o/585133.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[C++][opencv]opencv填充透明色到不规则polygon区域

大家用yolov5-seg分割都知道官方演示分割结果会把分割区域半透明填充到原图里面&#xff0c;那么C如何实现呢。今天特地研究了下。由于分割点是变动的&#xff0c;所以我们需要用变量控制分割点数。 参考文章写的很不错&#xff0c;但是有个毛病&#xff0c;他这个是5点必须是…

MySQL---JDBC基础操作、SQL注入

1. JDBC JDBC&#xff08;Java DataBase Connectivity,java数据库连接&#xff09;是一种用于执行SQL语句的Java API。 JDBC是Java访问数据库的标准规范&#xff0c;可以为不同的关系型数据库提供统一访问&#xff0c;它由一组用Java 语言编写的接口和类组成。 JDBC需要连接…

unreal 5.1 增强输入实现

在ue5.1版本增加了增强输入&#xff0c;并且废弃了之前的轴映射和操作映射。 官方文档地址&#xff1a;https://docs.unrealengine.com/5.1/zh-CN/enhanced-input-in-unreal-engine/ 输入动作&#xff08;Input Actions&#xff09; 更改后的区别我体验下来&#xff0c;它将…

探索 PlanetIX:解读区块链游戏运营的奥秘

作者: danielfootprint.network 熊市之中&#xff0c;PlanetIX 成长为最强的 Web3 游戏&#xff0c;在 Polygon 网络上独占鳌头。而其开发团队深度使用了 Footprint Analtics 的零代码数据分析平台和-GameFi 的数据 API 来提升用户的游戏体验。 近日&#xff0c;Footprint 与…

Visual Studio添加native tools command prompt

学习UEFI开发&#xff0c;环境设置种需要用到native tools command prompt&#xff0c;但是看了一下VS2017的Tools菜单下没有这个选项。网上查询&#xff0c;解决了问题&#xff1a; Tools > External Tools > Add Title:VS Command PromptCommand:C:\Windows\System32\…

操作系统原理 —— 内存管理的概念(十八)

为什么要有内存管理 为什么要对内存进行管理&#xff0c;需要解决什么问题&#xff1f; 要回答这个问题&#xff0c;首先我们需要明白&#xff1a;进程运行时&#xff0c;需放在内存才能运行。比如在执行一个程序时&#xff0c;需将该程序的相关数据与指令装入内存才能运行。…

家居购项目 (上)

文章目录 &#x1f400;Java后端经典三层架构&#x1f407;MVC模型&#x1f407;开发环境搭建&#x1f407;会员注册&#x1f333;前端验证用户注册信息&#x1f333;思路分析&#x1f349;创建表&#x1f349;创建实体类&#x1f349;DAO&#x1f34c;MemberDAOImpl &#x1f…

ISO21434 组织网络安全管理

目录 一、概述 二、目标 三、输入 3.1 先决条件 3.2 进一步支持信息 四、要求和建议 4.1 网络安全治理 4.2 网络安全文化 4.3 信息共享 4.4 管理系统 4.5 工具管理 4.6 信息安全管理 4.7 组织网络安全审计 五、输出 一、概述 为了实现网络安全工程&#xff0c;该…

Rotary Position Embedding (RoPE, 旋转式位置编码) | 原理讲解+torch代码实现

&#x1f525; RoPE为苏剑林大佬之作&#xff0c;最早应用于他自研的RoFormer (Rotary Transformer)&#xff0c;属于相对位置编码。效果优于绝对位置编码和经典式相对位置编码。出自论文&#xff1a;《RoFormer: Enhanced Transformer with Rotary Position Embedding》 &…

轻松高效!三种方法教你音频转文字!

我们在日常生活中&#xff0c;总会遇到许多需要音频转文字的情况。这个时候大部分小伙伴会选择一边播放音频一边记录的方式来整理音频的内容&#xff0c;这样既麻烦又费时&#xff0c;整理的效率也不高。其实我们只需要使用软件来协助我们将音频转换成文字&#xff0c;就可以很…

2023年03月六级真题全3套【可复制可划线查词】共11页PDF

2023年03月六级真题全3套【可复制可划线查词】共11页PDF 2023年03月六级真题全3套【可复制可划线查词】共11页PDF 2023年03月六级真题全3套【可复制可划线查词】共11页PDF

html基础知识总结

&#xff08;一&#xff09;html 1、html html&#xff1a;超文本标签语言&#xff0c;专门用来制作网页的一门语言。超文本&#xff1a;就是它不仅可以放文本内容&#xff0c;还可以是图片&#xff0c;声音&#xff0c;视频&#xff0c;多媒体等等内容 2、 html标签的分类 …

ASEMI双向可控硅BT137性能特点, BT137应用及购买指南

编辑-Z 本文将详细介绍可控硅BT137的性能特点、应用领域以及购买时需要注意的事项&#xff0c;帮助您更好地了解和选择BT137可控硅。 一、BT137可控硅简介 可控硅&#xff08;Silicon Controlled Rectifier&#xff0c;简称SCR&#xff09;是一种四层三端半导体器件&#xff…

sql 优化----》1)分析与定位策略

https://www.cnblogs.com/cshaptx4869/p/10482500.html 1&#xff1a;通过 show status 了解各种的SQL的执行频率 2&#xff1a;定位执行频率低的SQL语句: 1):通过慢日志定位 慢日志&#xff1a;可以通过两个方式配置 方式一&#xff1a;配置文件&#xff0c;my.cnf show_query…

25 # eventloop 执行流程

浏览器事件环 1、浏览器的进程 进程是计算机调度的基本单位&#xff0c;进程中包含着线程&#xff0c;浏览器是多进程进程&#xff0c;大致有下面几种 每一个页卡都是进程&#xff08;互不影响&#xff09;浏览器也有一个主进程&#xff08;用户界面&#xff09;每一个页卡里…

聊一聊行业的前景、就业方向和薪资待遇

软件测试行业是和软件开发相辅相成得一个行业&#xff0c;但目前大家对于软件测试行业的了解并不多&#xff0c;甚至很多学了软件测试的朋友也不是很了解。今天&#xff0c;就来给大家说一说&#xff0c;软件测试行业的前景、就业方向和薪资待遇。 岗位前景 很多小伙伴都曾听…

【PHPWord】PHPWord 根据word模板生成的内容动态生成目录以及页码

文章目录 一、需求分析二、PHPWord 中模板页码的设置三、模板内生成目录四、总结一、需求分析 在实际业务中,我们可能需要根据一些比较复杂的业务模板,生成对应的Word 文件。 本文将掌握: 使用模板配置页码使用模板插入目录二、PHPWord 中模板页码的设置 1.配置页码 注意…

dex2jar 报错 com.googlecode.d2j.DexException: not support version

​ 目录 ​ 一.问题发现 二.调查原因&#xff1a; 三. 根本原因调查&#xff1a; 四.解决问题 一.问题发现 使用dex2jar工具反编的时候&#xff0c;一输入指令&#xff0c;结果报com.googlecode.d2j.DexException: not support version错误(如下图) 异常情况.png 二.调查…

Autosar之自签名证书与CA证书

文章目录 一、安全传输1.框架2.如何实现传输安全&#xff1f;3. 对称加密和非对称加密的区别&#xff1f;4.伪随机数和真随机数5.数字签名 —— 验证完整性 & 认证数据来源6.为什么使用摘要算法的数字签名可以验证完整性&#xff1f;7.为什么数字签名可以认证数据来源&…

南开大学计算机考研分析

关注我们的微信公众号 姚哥计算机考研 更多详情欢迎咨询 南开大学&#xff08;B&#xff09;考研难度&#xff08;☆☆☆☆☆☆&#xff09; 南开大学计算机学科的研究工作始于1958年&#xff0c;是在实力雄厚的数学学科和物理学科的基础上发展起来的&#xff0c;是我国最早…