1. 什么是深拷贝?什么是浅拷贝?

不管是深拷贝还是浅拷贝,都是针对引用类型的。通俗的理解就是,深拷贝得到的对象不会受被拷贝对象影响,浅拷贝得到的对象与被拷贝对象之间相互影响。

2. 深拷贝的实现

  1. 方式一:手动深拷贝
let school = { name: "milly" }
let my = { age: { count: 18 }, name: "xy" }
let newMy = { ...my, age: { ...my.age } }
let all = { ...school, ...newMy }
console.log(all)my.age.count = 100
console.log(my)
console.log(all)  // { name: 'xy', age: { count: 18 } }

注意: 展开运算符本身是浅拷贝。Object.assign()等同于...,也是浅拷贝。

  1. 方式二:先把对象转换成字符串, 然后把字符串转换成对象
let school = { name: "milly" };
let my = { age: { count: 18 }, name: "xy" };
let all = JSON.parse(JSON.stringify({ ...school, ...my }));
console.log(all)my.age.count = 300
console.log(my)  // { age: { count: 300 }, name: 'xy' }
console.log(all)  // { name: 'xy', age: { count: 18 } }

这种深拷贝的方式存在一定的问题:不能拷贝函数、undefined、时间、正则,测试看一下:


  1. 方式三:封装一个深拷贝 — 递归拷贝

首先, 我们可以判断数据类型的方式有:typeofinstanceofObject.prototype.toString.call()constructor

先来看下浅拷贝函数是如何封装的:

function deepClone(obj) {if (obj == null) {return obj}if (obj instanceof Date) {return new Date(obj)}if (obj instanceof RegExp) {return new RegExp(obj)}if (typeof obj !== 'object' ) {return obj}let cloneObj = new obj.constructor()for (let key in obj) {if (obj.hasOwnProperty) {cloneObj[key] = obj[key]}}return cloneObj
}

如何修改成深拷贝呢? 其实, 深拷贝 = 浅拷贝+递归

function deepClone(obj) {if (obj == null) {return obj}if (obj instanceof Date) {return new Date(obj)}if (obj instanceof RegExp) {return new RegExp(obj)}if (typeof obj !== 'object' ) {return obj}let cloneObj = new obj.constructor()for (let key in obj) {if (obj.hasOwnProperty) {cloneObj[key] = typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key]}}return cloneObj
}// 测试
let obj = {school: { name: { first: "mengmeng", last: "Liu" }, age: 18 },fn: function () {},aa: undefined,b: null,arr: [1, 2, 3],
}
let obj2 = deepClone(obj)
console.log(obj2)obj2.school.age = 100
console.log(obj)

上述深拷贝函数已经能够实现开始的功能了,但是如果是拷贝自身的话,即obj.xxx=obj,就会陷入死循环, 如何解决这个问题呢? 使用 弱引用 Map weakMap Set weakSet。

3. 使用弱引用解决深拷贝中递归死循环的问题

function deepClone(obj, hash = new WeakMap()) {if (obj == null) {return obj}if (obj instanceof Date) {return new Date(obj)}if (obj instanceof RegExp) {return new RegExp(obj)}if (typeof obj !== 'object' ) {return obj}// 如果拷贝的是一个已经存在的对象,那就直接从WeakMap中返回即可if (hash.has(obj)) { return hash.get(obj) }let cloneObj = new obj.constructor()hash.set(obj, cloneObj)for (let key in obj) {if (obj.hasOwnProperty) {cloneObj[key] = typeof obj[key] === 'object' ? deepClone(obj[key], hash) : obj[key]}}return cloneObj
}

4. 如何解决深拷贝中可能出现的爆栈问题? — 迭代?

深拷贝与浅拷贝深入理解相关推荐

  1. 面试官:谈谈你对深拷贝和浅拷贝的理解

    在面试的时候,如果面试官问对你说:请谈谈你对深拷贝和浅拷贝的理解,你会怎么回答这个问题呢?可能有很多小伙伴都不太理解深拷贝和浅拷贝的含义和区别,那么今天就和各位小伙伴分享一下我对二者的理解

  2. 深拷贝和浅拷贝的理解-----------【Java基础】

    拷贝,在IT界是一个计算机系统的DOS命令,意为"复制",是一个新名词,广泛地应用于IT的各个领域: 拷贝还分深拷贝和浅拷贝:拷贝的对象不同还会导致拷贝方式的不同:拷贝的若是引用数 ...

  3. python深拷贝和浅拷贝的使用场景_深拷贝、浅拷贝的理解与使用场景

    什么是深拷贝.浅拷贝? 通俗解释:深拷贝是内容拷贝,浅拷贝是地址拷贝 区别点: 深拷贝会创建一个新的内存空间,拷贝的值是一样的,但是内存地址不一样. 浅拷贝只是拷贝指向原来对象的地址,使原对象的引用计 ...

  4. 深拷贝和浅拷贝的理解

    深拷贝和浅拷贝就是指对象的拷贝,一个对象中存在两种类型的属性,一种是基本数据类型,一种是实例对象的引用. 1.浅拷贝是指,只会拷贝基本数据类型的值,以及实例对象的引用地址,并不会复制一份引用地址所指向 ...

  5. 深拷贝和浅拷贝的理解与应用

    对象拷贝就是将一个对象的属性拷贝到另一个有着相同类型的对象中去.java中有两种类型的对象拷贝:深拷贝.浅拷贝. 假如我们要复制一对基本数据类型变量到另外一个具有相同的类型的基本变量时,我们一般会这样 ...

  6. 浅谈对java深拷贝与浅拷贝的理解

    java中什么是浅拷贝?什么是深拷贝? 1.拷贝:实现对象复制的方式. 2.浅拷贝:被复制的对象的所有变量都含有原来对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之, 浅拷贝仅仅复制所 ...

  7. 对深拷贝与浅拷贝的再次理解

    对深拷贝与浅拷贝的再次理解 记得11年底找工作的时候,面试时曾经遇到有面试官问的对深拷贝与浅拷贝的理解,那时候自己回来查了资料,写了篇博客,感觉自己理解了,其实理解的不深刻,最近在调试bug的时候,再 ...

  8. Javascript中的深拷贝和浅拷贝

    文章目录 JavaScript中的变量类型 深拷贝和浅拷贝的理解 深拷贝和浅拷贝的实现方式 为什么需要深拷贝和浅拷贝 JavaScript中的变量类型 (1).基本类型 JavaScript中的基本类 ...

  9. PHP中对象的深拷贝与浅拷贝

    2019独角兽企业重金招聘Python工程师标准>>> 最近写了一个php脚本,在脚本中使用到了SplPriorityQueue,会用到两次 因此写了如下: $res=$tmp_re ...

最新文章

  1. 无线路由器与无线AP的区别
  2. 重磅!分布式数据库解决方案Apache ShardingSphere毕业成为顶级项目
  3. Raspberry Zero 上实现平滑视频图传
  4. 我的ubuntu8.04安装经验 (转)
  5. 提权函数之RtlAdjustPrivilege()
  6. linux+crontab执行php,如何使用Linux的Crontab执行PHP脚本
  7. java(3)——数据类型中的数值型的整数类型
  8. 新疆计算机一级考试试题视作题,2014新疆计算机一级考试试题汇总
  9. 有三个数a,b,c,要求按大小顺序输出。
  10. 深入理解 main 方法
  11. N个Linux耍酷命令,手把手教你如何技术撩妹!
  12. 引用opencv异常
  13. 【优化算法】差分蜂群优化算法(DEABC)【含Matlab源码 1423期】
  14. H13-531 华为HCIE云计算笔试题库整理
  15. QAM调制原理_QAM调制:4/5G中各种调制方式基础,均由两条正弦波变化并勾勒出...
  16. 一种DC-DC转换器的分析
  17. 普渡大学计算机工程专业提前毕业,Purdue的ECE「普渡大学西拉法叶分校电气与计算机工程学院」...
  18. 2021年中国饮料酒产业链及产量现状分析:产量同比增长2.73%[图]
  19. 网络安全之手机安全使用手册
  20. vjdesign - vue 界面可视化设计器

热门文章

  1. 面试官系统精讲Java源码及大厂真题 - 33 CountDownLatch、Atomic 等其它源码解析
  2. Nginx的HTTP运行时健康检查
  3. 容器编排技术 -- Kubernetes kubectl create poddisruptionbudget 命令详解
  4. 容器编排技术 -- Kubernetes是什么?
  5. 服务器上使用docker安装部署禅道zentao
  6. Java数组在内存中的分配
  7. /etc/passwd文件+/etc/shadow文件(图解+字段详解)
  8. 【Vue.js 3.0】不使用根标签,Error:[vue/no-multiple-template-root] The template root requires exactly one ...
  9. 亚马逊云服务开通指南_亚马逊弹性容器服务初学者指南
  10. 小程序开发 宽度100%_这是您作为开发人员可以实现100%年度目标的方式