摘要:之所以会出现深浅拷贝的问题,实质上是由于JS对基本类型和引用类型的处理不同。

本文分享自华为云社区《js的深浅复制,一看就明白》,作者: 鑫2020。

浅复制的意思

浅复制是仅仅对数据存放在栈内的引用的复制,没有复制引用指向堆内的内容。多个数据的浅复制,这复制多个引用,这多个引用共同指向堆内的同一个内容。当一个浅复制数据做出修改,即堆内的引用指向的内容发生修改,这时,其他通过引用指向这里的数据也会随着改变。

let obj = {a:1,b:2,c:{c1:10,c2:20}
}let objA = obj;
objA.a = 'a';console.log(obj.a);  // 'a'
console.log(objA.a);  // 'a'

深复制的意思

深复制是指连同堆的内容一块复制,生成一个新的对象。多个深复制将是多个不同的对象,也就有不同的引用,也就指向不同的堆内容。

使用深复制的原由

在平常开发中,有时会有数据的传递与接收,当拿到传过来的数据后,难免需要对数据进行加工和改造,为了不破坏原有数据结构,这时就可以使用深复制拷贝数据,然后处理生成的新的数据。深复制也可以防止修改多个引用后引用混乱的问题,减少BUG的产生机会。

可实现深复制的几种方法

实现方式一:JSON的序列化与反序列化

let obj = {a:1,b:2,c:{c1:10,c2:20}
}let objA = JSON.parse(JSON.stringify(obj));//JSON的序列化与反序列化
objA.a = 'a';console.log(obj.a);  // 1
console.log(objA.a);  // 'a'

虽然JSON的序列化与反序列化可以实现深复制,但有几个缺点需要注意:
1、date日期对象被转成日期日期字符串
2、没法访问到原型
3、复制不了undefined的属性
4、NAN和无穷被转为NULL

let d1 = new Date();
let obj = {d1,d2: undefined,d3:NaN
}
let objD = JSON.parse(JSON.stringify(obj));
console.log(obj)
console.log(objD)

实现方式二:Object.assign()

let obj = {a:1,b:2,c:{c1:10,c2:20}
}let objA = Object.assign(obj);
objA.a = 'a';console.log(obj.a);  // 1
console.log(objA.a);  // 'a'

虽然Object.assign()可以实现深复制,但对于更深层次的对象引用也是仅仅浅复制。

let obj = {a:1,b:2,c:{c1:10,c2:20}
}let objA = Object.assign(obj);
objA.c.c1 = 'c1'; //Object.assign()仅仅是一层深复制。console.log(obj.c.c1);  // 'c1'
console.log(objA.c.c1);  // 'c1'

实现方式三:扩展运算符

let obj = {a:1,b:2,c:{c1:10,c2:20}
}let objA = {...obj};;
objA.a = 'a';console.log(obj.a);  // 1
console.log(objA.a);  // 'a'

虽然扩展运算符"…"可以实现深复制,但对于更深层次的对象引用也是仅仅浅复制。

let obj = {a:1,b:2,c:{c1:10,c2:20}
}let objA = {...obj};
objA.c.c1 = 'c1'; //扩展运算符"..."同Object.assign()一样,仅仅是一层深复制,不能多层深复制。console.log(obj.c.c1);  // 'c1'
console.log(objA.c.c1);  // 'c1'

实现方式四:使用递归

想要实现深复制,且实现多层深复制则可以使用递归循环复制。

let obj = {a:1,b:2,c:{c1:10,c2:20}
}const ReCopy = function (paramter) {let target = null;let isObject = paramter.constructor === Object;let isArray = paramter.constructor === Array;if (isObject || isArray) {target = Array.isArray(paramter) ? [] : {};for (let i in paramter) {target[i] = ReCopy(paramter[i]);}} else {target = paramter;}return target;}let objA = ReCopy(obj);
objA.c.c1 = 'c1';console.log(obj.c.c1);  // 10
console.log(objA.c.c1);  // 'c1'

ladash深拷贝

lodash深复制是更专业的深复制方式。

  • 安装lodash
    先初始化,生成package.json文件,然后使用一下命令安装。
npm i -S lodash
  • 引入lodash
var _ = require('lodash');
  • 使用lodash
let obj = {a:1,b:2,c:{c1:10,c2:20}
}let objA = _.cloneDeep(obj);
objA.c.c1 = 'c1'; console.log(obj.c.c1);  // 10
console.log(objA.c.c1);  // 'c1'

点击关注,第一时间了解华为云新鲜技术~

JS的深浅复制,原来如此!相关推荐

  1. js中的深浅复制(深浅拷贝、深浅克隆)

    什么是浅复制? --把一个变量赋值给另一个变量,基本数据类型如数字,字符串,布尔值等这些是拷贝值,引用数 据类型如对象,数组,函数等,这些拷贝的是地址. 深复制: 将一个对象从内存中完整的拷贝一份出来 ...

  2. 深浅复制的的理解与区别

    深浅复制的的理解与区别 1.浅复制,仅仅是复制对象本身,并没有对所含的的对象进行复制,仅仅是对所含的对象进行Retain一下,引用计数加1 2.深复制,不仅仅对对对象本身进行复制,还对所含的对象进行复 ...

  3. python json数据格式数组内元素递增赋值_python深浅复制,类型转换, json操作,数组操作...

    python深浅复制 import copy a = [1, 2, 3, 4, ['a', 'b']] #原始对象 b = a #赋值,传对象的引用 c = copy.copy(a) #对象拷贝,浅拷 ...

  4. js实现一键复制到剪切板上_你的“剪切板”正在被网赚者控制

    谈这个话题之前,我们得先了解它们为什么要操控我们得剪切板 答案当然是为了:"羊毛" 这个行业有个专业名字叫做:自动化网赚 有些时候你去查资料,就莫名其妙打开了某宝领了某个小红包.可 ...

  5. js实现一键复制到剪切板上_js实现各种复制到剪贴板的方法

    一.实现点击按钮,复制文本框中的的内容 function copyUrl2() { var Url2=document.getElementById("biao1"); Url2. ...

  6. js点击复制文本 - 案例篇

    文章目录 js点击复制文本 :代码+效果图 效果图 · 示下: html 代码如下: 注意代码: 附:[javascript监听键盘事件 - 如表单enter回车提交](https://blog.cs ...

  7. 原型模式(Prototype)以及深浅复制

    5.原型模式(Prototype) view plaincopy public class Prototype implements Cloneable { public Object clone() ...

  8. jq的深浅复制:extend()

    jq的深浅复制是通过extend()方法来实现的: 用法:$.entend(),可以传多个参数: 浅拷贝:$.entend(参数1,参数2,参数3...): 含义是:把参数2,参数3及浅拷贝给参数1: ...

  9. js实现粘贴板js插件clipboard.js实现一键复制粘贴功能

    js实现粘贴板js插件clipboard.js实现一键复制粘贴功能 简介 下载 引入插件 使用 一个节点的复制 多个节点的复制 剪切文本框 复制输入框 简介 clipboard.js 提供了一种更好. ...

最新文章

  1. Linux13-计划任务crontab
  2. 计算机excel教程文字版,Excel函数教程:文本函数
  3. Shell命令-内置命令及其它之exec、export
  4. 使用Java实现的简单的计算器
  5. 软件设计原则(七)合成/聚合复用原则(Composite/Aggregate Reuse Principle,CARP)
  6. Flowable 数据库表结构 ACT_RE_MODEL
  7. 修复版超强大微信小程序源码-内含几十款功能王者战力查询
  8. 【ES6】Set Map数据结构、Iterator遍历器
  9. Mysql 异步复制
  10. [NOIp 2009]Hankson的趣味题
  11. shell基础09 归档数据
  12. Reinforcement Learning An Introduction~The 10-armed Testbed
  13. 磁盘显示数据错误循环冗余检查资料怎么寻回
  14. 卡西欧计算机储存数据,卡西欧计算器(统计计算)操作.ppt
  15. [NLP]高级词向量表达之Word2vec详解(知识点全覆盖)
  16. 问个问题(nimultisim14.0双开关)
  17. Python | 实现简单的康威生命游戏
  18. Linux内核中断处理“下半部”机制(超详细~)
  19. ASM 系列详细教程-02-ASM 整体概览
  20. class_addMethod的详解

热门文章

  1. 物联网linux_Linux的未来,Google的物联网标准等
  2. JavaScript实现元素全排列
  3. Bootstrap按钮组嵌套
  4. Bootstrap 折叠插件Collapse 事件
  5. Bootstrap源代码多行代码
  6. php程序控制结构,PHP 控制结构
  7. php实现数字英文验证码,PHP英文数字验证码生成类
  8. ROS笔记(30) Movelt!配置文件
  9. 谈一下对c语言程序设计,谈《C语言程序设计》课程教学.doc
  10. 软件版本号命名规范_如何才能给文件合理命名,提高工作效率?我有3个建议!...