深拷贝和浅拷贝的区别,如何实现一个深拷贝

ops/2025/2/22 15:41:26/

在JavaScript中,数据类型分为基本数据类型和引用数据类型。

基本数据类型是保存在栈内存中的,引用数据类型的变量是一个指向堆内存中实际对象的引用,这个引用是保存在栈内存中。

浅拷贝

浅拷贝,指的是创建新的数据。

如果原始数据的属性是基本类型,那拷贝的就是基本类型的值;如果原始数据的属性是引用类型,那拷贝的就是内存地址。浅拷贝是拷贝一层,引用类型部分共享内存地址。

实现一个浅拷贝功能的函数

javascript">function shallowClone(obj) {const newObj = {};for (const key in obj) {if (obj.hasOwnProperty(key)) {newObj[key] = obj[key]}}return newObj
}

在JavaScript中,提供一个浅拷贝的函数:

  • Object.assign()
  • 使用拓展运算符实现复制
  • Array.prototype.slice()和Array.prototype.concat()

Object.assign

javascript">var obj = {age: 18,nature: ['smart', 'good'],names: {name1: '11',name2: '222'},love: function () {console.log('33333')}
}
var newObj = Object.assign({}, obj)

slice()

javascript">const fxArr = ["One", "Two", "Three"]
const fxArrs = fxArr.slice(0)
fxArrs[1] = "love";
console.log(fxArr) // ["One", "Two", "Three"]
console.log(fxArrs) // ["One", "love", "Three"]

concat()

javascript">const fxArr = ["One", "Two", "Three"]
const fxArrs = fxArr.concat()
fxArrs[1] = "love";
console.log(fxArr) // ["One", "Two", "Three"]
console.log(fxArrs) // ["One", "love", "Three"]

使用拓展运算符实现复制

javascript">const fxArr = ["One", "Two", "Three"]
const fxArrs = [...fxArr]
fxArrs[1] = "love";
console.log(fxArr) // ["One", "Two", "Three"]
console.log(fxArrs) // ["One", "love", "Three"]

深拷贝

深拷贝是开辟一个新的内存空间,两个对象属性完全相同,但是对应的两个不同地址。修改一个对象的属性,不会影响另一个对象。

常见的深拷贝函数:

  1. _.cloneDeep(),lodash库中的一个函数
  2. JSON.stringify()
  3. 手写循环递归

其中的JSON.stringify()会有一些弊端,它会忽略undefined 、Symbol和函数。

循环递归

javascript">function deepClone(obj, hash = new WeakMap()) {if (obj === null) return obj; // 如果是null或者undefined,就不进行遍历if (obj instanceof Date) return new Date(obj);if (obj instanceof RegExp) return new RegExp(obj);if (typeof obj !== "object") return obj;// 普通值或者函数,不需要遍历if (hash.get(obj)) return hash.get(obj);let cloneObj = new obj.constructor();hash.set(obj, cloneObj);for (let key in obj) {if (obj.hasOwnProperty(key)) {cloneObj[key] = deepClone(obj[key], hash);}}return cloneObj;
}

http://www.ppmy.cn/ops/36686.html

相关文章

技术周总结 2024.04.29-05.05

文章目录 一、python的数据表处理二、05.05 周日2.1)python的一些语法2.2)Dubbo2.3) Golang 一、python的数据表处理 1)代码作用 下边的代码主要是涉及 python链接数据库,并从数据库中获取到 元祖的返回结果,继续对返…

软件开发者如何保护自己的知识产权?

最近一个关于开源软件的知识产权纠纷的案例,非常有代表性, 其中涉及到的平台openwrt,一口君十几年前曾玩过, 通过这个案例,我们可以学习如何在今后工作中保护自己的知识产权, 以及如何合理直接或者间接利…

成为黑客第一步,应该从熟练掌握运维常见的工具开始

目录 1. 开发工具 2. 自动化构建和测试 3. 持续集成与交付(CI/CD) 4. 部署工具 5. 维护 6. 监控,警告&分析 1. 开发工具 代码编辑器和IDE(集成开发环境):如Visual Studio Code、IntelliJ IDEA和E…

如何在交换机上重置密码而不丢失配置?如何配置SSH远程登录?

在网络设备管理中,保持设备的安全性是至关重要的,所以console密码是必须设置的,绝对不能偷懒。 但是,如果习惯不好,或者离职时交接不好,就会导致密码丢失,此时想要修改网络设置的配置就麻烦了。…

新唐的nuc980/nuc972的开发1-环境和源码同步

开发环境安装 1.1更新源 服务器端:可以参考:Linux替换清华源_更改清华源-CSDN博客 下面是桌面端的方法: 打开系统的软件中心,选择自己想要使用的源 更新缓存 1.2安装必须的库 apt-get install patch apt-get install libc6-dev …

【Linux系列】file命令

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

xhell + privoxy 手动http代理设置

xshell7 SSH -> 隧道 -> 添加 -> 类型:Dynamic(SOCKS4/5) 侦听端口:1080 privoxy https://www.privoxy.org/ 下载zip版本 解压到 E:\httpserver\privoxy_3.0.34 config.txt 中 添加 listen-address 0.0.0.0:8118 forward-socks5 / 127.0.0.1:1080 . windows11 …

Python Dash库:一个Web应用只需几行代码

大家好,在数据科学领域,数据可视化是将数据以图形化形式展示出来,帮助我们更直观地理解数据。Python中有一个非常流行的数据可视化库叫做Dash,Dash以其简洁、高效和强大的功能而闻名,它允许开发者快速构建交互式Web应用…