深拷贝和浅拷贝是两种JavaScript中常见的变量赋值方式。假设有一个对象obj,它包含了若干属性和方法,请看下面的讲解:

  1. 浅拷贝
    在对象的浅拷贝中,新对象只是简单地复制原始对象在内存中存储的地址,而不是其实际数据。也就是说,新对象的改变会影响到原始对象。
    例如,当使用Object.assign()函数或…操作符时,它只复制了原始对象可枚举的自身属性,未能深递归到子对象中。
    下面是一个针对对象的浅拷贝代码示例:
// 定义一个原始对象
let obj = { a: 10, b: 20 }// 浅拷贝至新对象
let newObj = Object.assign({}, obj);// 改变新对象中的属性值
newObj.b = 30;
console.log(obj.b); // 20
console.log(newObj.b); // 30

从示例中可以看到,虽然已更改“newObj”对象的“b”属性,但并未影响到原始对象中的值。
2. 深拷贝
相反地,在深拷贝中,当执行对象之间的复制时,每个属性会被递归地拷贝,新的对象被分配了一个不同的内存地址,这表示在新对象上的更改不会影响原始对象。
例如,可以使用JSON(JavaScript Object Notation)内置函数JSON.parse()和JSON.stringify()将对象深拷贝到新对象中。但该方法也有限制, 无法复制一些 JS 对象特性(如 function, Infinity 等), 以及内置对象本身(如 Date, Map等)。
下面是一个针对对象的深拷贝代码示例:

// 定义一个原始对象
let obj = { a: 10, b: { c: 20 } }// 深拷贝至新对象
let newObj = JSON.parse(JSON.stringify(obj));// 改变新对象中的属性值
newObj.b.c = 30;
console.log(obj.b.c); // 20
console.log(newObj.b.c);

或通过递归实现

function deepClone(obj) {if (obj === null || typeof obj !== 'object') {// 如果是null、undefined、字符串、数字、布尔值等基本类型数据,直接返回return obj;}let clone = Array.isArray(obj) ? [] : {}; // 判断是数组还是对象for (let key in obj) {if (obj.hasOwnProperty(key)) { // 判断是否为自身属性clone[key] = deepClone(obj[key]); // 递归进行深拷贝}}return clone;
}

该函数首先判断传入的参数是否为null或基本类型,如果是直接返回该值;否则就创建一个新的对象或数组,然后遍历原对象或数组的每个属性/元素,并递归地复制其对应的值到新数组或对象中。
需要注意的是,在进行深拷贝时,我们使用了hasOwnProperty来判断是否为自身属性,这是因为JavaScript中所有对象都继承自Object.prototype,并在原型链上定义了一些可枚举的属性。所以如果不使用hasOwnProperty,函数有可能会复制到原型对象上的属性。

深拷贝的循环引用问题

当以上深拷贝遇到循环引用时,会发生无限递归的情况,如:

const obj = {arr: [1, 2, 3],a: 4
};
obj.sub = objobj.arr.push(obj)

此情况如果使用上述深拷贝,会出现无限递归。
解决方法:可以使用缓存来解决。
具体思路:在外部定义一个存放缓存的变量,来缓存克隆的map结构,当判断拷贝的对象时对象类型时,读取缓存是否包含此对象,如有直接return出去,如果没有则添加。这样就可以解决循环引用时,发生无限递归的问题了。

function deepClone(value) {// 定义缓存const cache = new WeakMap() //最好不要使用map() 来克隆结构,会影响垃圾回收.而WeakMap 不影响function _deepClone(obj) {if (obj === null || typeof obj !== 'object') return obj// 判断是否存在if (cache.has(obj)) {return cache.get(obj) //存在 return }let clone = Array.isArray(obj) ? [] : {};// 不存在,添加cache.set(obj, clone)for (let key in obj) {if (obj.hasOwnProperty(key)) {clone[key] = _deepClone(obj[key])}}return clone}return _deepClone(value)
}

谈一谈浅拷贝和深拷贝相关推荐

  1. 来谈一谈深拷贝和浅拷贝的方法?

    豆芽今天来谈一谈深拷贝和浅拷贝的区别和使用的方法. 二者的区别 区别建立在针对引用类型 浅拷贝:重新在堆中创建内存,拷贝前后对象的基本数据类型互不影响,但拷贝前后对象的引用类型因共享同一块内存,会相互 ...

  2. 谈一谈Java中的深拷贝和浅拷贝

    在 Java 开发中,对象拷贝或者说对象克隆是常有的事,对象克隆最终都离不开直接赋值.浅拷贝.深拷贝 这三种方式,其中直接赋值应该是我们最常用的一种方式吧,对于浅拷贝和深拷贝可能用的少,所以或多或少存 ...

  3. JavaScript 面向对象编程(三) —— 函数进阶 / 严格模式 / 高阶函数 / 闭包 / 浅拷贝和深拷贝

    本篇为 JavaScript 进阶 ES6 系列笔记第三篇,将陆续更新后续内容.参考:JavaScript 进阶面向对象 ES6 :ECMAScript 6 入门 系列笔记: JavaScript 面 ...

  4. 关于浅拷贝、深拷贝的探究

    浅拷贝.深拷贝.完全拷贝 在这里介绍三个概念: 浅拷贝:在拷贝操作时,对于被拷贝的对象的每一层拷贝都是指针拷贝. 深拷贝:在拷贝操作时,对于被拷贝的对象至少有一层拷贝是对象拷贝. 完全拷贝:在拷贝操作 ...

  5. 一篇文章彻底搞懂浅拷贝和深拷贝

    强烈推荐30个原生JavaScript的demo,包括canvas时钟特效.自定义视频播放器.搜索栏快速匹配.fetch访问资源.console调试技巧等,先fork后学习,详见​​​​​点击打开查看 ...

  6. js对象的直接赋值、浅拷贝与深拷贝

    最近Vue项目中写到一个业务,就是需要把对话框的表单中的数据,每次点击提交之后,就存进一个el-table表格中,待多次需要的表单数据都提交进表格之后,再将这个表格提交,实现多个表单数据的同时提交,期 ...

  7. Java中的浅拷贝与深拷贝

    一.引用拷贝与对象拷贝 class Person implements Cloneable{private String name;private int age;...省略get和set方法 pro ...

  8. 谈一谈浏览器解析CSS选择器的过程【前端每日一题-6】

    谈一谈浏览器解析CSS选择器的过程? 这是一道发散题,可以根据自己的理解自行解答. 在开始前,我们必须了解一个真相:为什么排版引擎解析 CSS 选择器时一定要从右往左解析? 简单的来说:浏览器从右到左 ...

  9. 有一群200w年薪的朋友是什么感觉?谈一谈入学中国科学院大学的几点感受吧

    我叫阿广,偶尔正经,偶尔逗比,97年生人,在求学期间当过鸡头鸡尾,当过凤尾没当过凤头.大家如果想深入了解我,可以查看本公众号的原创文章. 技术人光有技术走不长久,所以今天不更新技术文章了,也给大家谈一 ...

  10. js之浅拷贝和深拷贝

    js数据类型主要分基本数据类型和引用数据类型.前者包括Number,String等,后者主要是Object,因此以下会针对不同的数据类型来分析,需要的朋友可以参考一下 1.js内存 js内存,或者说大 ...

最新文章

  1. leetcode 30. Substring with Concatenation of All Words 与所有单词相关联的字串 滑动窗口法
  2. controller是什么意思_光谈理论有什么意思,附源码带大家实操SpringBoot
  3. exsi主机之间使用scp拷贝文件超时问题
  4. 可视化篇(四)——— python绘制双y轴、箱线图、概率分布三种图形及案例
  5. 可以扣6分也可以扣0分?闯红灯也是有技巧的
  6. 1982:【19CSPJ普及组】数字游戏 scratch C++
  7. 苹果手机怎么编辑word文档_可以一键导入word图文的微信编辑软件有什么?编辑器怎么使用?...
  8. 5 | Spatial-based GNN/convolution模型之DGC
  9. c#使用SHA256算法实现对文件的加密和解密
  10. golang实现文件服务器,【Golang】实现文件服务器断点续传
  11. 虚拟化实验室推进计算机网络专业实践教学的解决方案
  12. 语音识别系统原理介绍----gmm-hmm
  13. 【Python爬虫+js逆向】使用Python爬取腾讯漫画的逆向分析(典型签名验证反爬虫的解决方案)——以腾讯动漫《一人之下》第一话为例
  14. word刷子刷格式_Word文档中格式刷怎么用?
  15. 思科路由器的双出口nat研究
  16. 【双轨】加权分红+三级分销+见点奖+级差源码系统 演示网站介绍
  17. apiCloud实现微信分享功能
  18. 做数据分析如何选择适合的数据图表(5类分析方法)
  19. 0day安全:软件漏洞分析技术 学习分析记录
  20. prop-types详解

热门文章

  1. 计算机辅助制造工具,计算机辅助制造
  2. 基于JavaSwing的学生考勤管理系统设计与实现
  3. android4.0源码目录结构
  4. C# 大头贴(小巧大头贴)
  5. vue3 template
  6. Wi-Fi技术改变应用
  7. Camtasia视频输出参数
  8. SystemVerilog搭建APB_I2C IP 层次化验证平台
  9. ubuntu 终端设置代理上网后,如何清楚代理设置
  10. MySQL学习【个人笔记/已完结】