首先,值的拷贝,通常有三种方式,由于基本类型与引用类型在内存中存储位置和存储方式的不同,导致了以下三种概念的衍生:

  • = 赋值:多个指针指向的是同一个堆中的地址,所以相互有影响;
  • 浅拷贝:在堆中重新创建内存,拷贝前后基本数据类型不受影响,但只拷贝一层,无法拷贝子对象;所以改变浅拷贝得到的对象中的引用类型时,原始数据会受到影响;例如数组的concat和slice方法;
  • 深拷贝:对子对象也可以拷贝,拷贝前后两个对象互不影响,是对对象以及对象的所有子对象进行拷贝;思路就是递归调用浅拷贝的逻辑,把所有属于对象的属性类型都遍历赋给另一个对象即可。完全的拷贝一个对象,即使嵌套了对象,两者也相互分离,修改一个对象的属性,也不会影响另一个。

看下数组结构的拷贝:

var new_arr = JSON.parse( JSON.stringify(arr) );复制代码

但此法无法拷贝函数。concat、slice、JSON.stringify 都算是技巧类,可以根据实际情况适当使用。

初步实现一个浅拷贝:

在看开源项目的过程中,经常会看到类似如下的源码。for...in循环对象的所有枚举属性,然后再使用hasOwnProperty()方法来忽略继承属性。

const shallowClone = (obj) => {  if (typeof obj !== 'object') returnlet newObj = obj instanceof Array ? [] : {}  for (let key in obj) {    if (obj.hasOwnProperty(key)) {      newObj[key] = obj[key]    }  }return newObj
}复制代码

初步实现一个深拷贝:

const deepClone = (obj) => {  if (typeof obj !== 'object') returnlet newObj = obj instanceof Array ? [] : {}  for (let key in obj) {    if (typeof obj[key] === 'object') {      newObj[key] = deepClone(obj[key])    } else {      newObj[key] = obj[key]    }  }return newObj
}复制代码

深拷贝会完全的克隆一个新对象,但因为使用递归,性能会不如浅拷贝,在开发中,还是要根据实际情况进行选择。

第三方库的实现

Underscore _.clone()

实际上是一种浅复制 (shallow-copy),所有嵌套的对象和数组都是直接复制引用而并没有进行深复制。源码:

// Create a (shallow-cloned) duplicate of an object.
_.clone = function(obj) {if (!_.isObject(obj)) return obj;return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
};复制代码

jQuery $.extend()

var x = {a: 1,b: { f: { g: 1 } },c: [ 1, 2, 3 ]
};var y = $.extend({}, x),          //shallow copyz = $.extend(true, {}, x);    //deep copyy.b.f === x.b.f       // true
z.b.f === x.b.f       // false复制代码

lodash  _.clone() / _.cloneDeep()

在lodash中关于复制的方法有两个,分别是_.clone()_.cloneDeep()。其中_.clone(obj, true)等价于_.cloneDeep(obj)

jQuery 无法正确深复制 JSON 对象以外的对象,而 lodash 花了大量的代码来实现 ES6 引入的大量新的标准对象。lodash 针对存在环的对象的处理也是非常出色的。因此相较而言,lodash 在深复制上的行为反馈比前两个库好很多。

参考源:

https://juejin.im/post/59ac1c4ef265da248e75892b

https://segmentfault.com/a/1190000002801042

https://github.com/mqyqingfeng/Blog/issues/32

js deep clone 深克隆相关推荐

  1. 深拷贝(deep clone)与浅拷贝(shallow clone)

    深拷贝(deep clone)与浅拷贝(shallow clone) 浅复制(浅克隆):被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复 ...

  2. 小和尚学习 - JS shallow clone 和 deep clone

    决定一个人的一生,以及整个命运的,只是一瞬之间.--歌德 目录 浅克隆 深克隆 丐中丐版 大众版 升级版 终极版 今天,小和尚和大伙聊聊一个面试家常菜:请手写一个 JS 深克隆. 在正式开始前,先了解 ...

  3. java deep clone util_Java Clone深拷贝与浅拷贝的两种实现方法

    1.首先,你要知道怎么实现克隆:实现Cloneable接口,在bean里面重写clone()方法,权限为public. 2.其次,你要大概知道什么是地址传递,什么是值传递. 3.最后,你要知道你为什么 ...

  4. java deep clone util_实现对象深度克隆(deepClone)的三种方案

    转:http://www.cnblogs.com/wangzhichao/archive/2013/04/11/3014419.html 方案一:利用现代浏览器支持的JSON对象做一次中转,实现深度克 ...

  5. java中的深浅克隆

    假设有一个对象object,在某处又需要一个跟object一样的实例object2,强调的是object和object2是两个独立的实例,只是在开始的时候,他们是具有相同状态的(属性字段的值都相同). ...

  6. JS 开发常用工具函数

    本文原载于SegmentFault专栏 作者:hfhan 整理编辑:SegmentFault 1.isStatic:检测数据是不是除了symbol外的原始数据 function isStatic(va ...

  7. (转载)jQuery 1.6 源码学习(一)——core.js[1]之基本架构

    在网上下了一个jQuery 1.2.6的源码分析教程,看得似懂非懂,于是还是去github上下载源码,然后慢慢看源代码学习,首先来说说core.js这个核心文件吧. jQuery整体的基本架构说起来也 ...

  8. 国庆假 的CSS +JS 学习笔记

    1.左右两列定宽,中间自适应, 6. 一个div 中,放三个div ,其中左边和右边是150px,中间div 自适应宽度. left center right .content{ background ...

  9. 学习 jQuery 源码整体架构,打造属于自己的 js 类库

    虽然现在基本不怎么使用 jQuery了,但 jQuery流行 10多年的 JS库,还是有必要学习它的源码的.也可以学着打造属于自己的 js类库,求职面试时可以增色不少. 本文章学习的是 v3.4.1版 ...

最新文章

  1. Bytom BIP-32协议和BIP-44协议解读
  2. 「AHOI / HNOI2018」转盘 解题报告
  3. Oracle免安装绿色版-PLSQL连接报12154
  4. Windows进程与线程学习笔记(三)—— KPCR
  5. iframe_demo实例:消息发送(PHP版本)
  6. Scala学习(十二)高阶函数
  7. Memcached未授权访问漏洞记录(CVE-2013-7239、危害级别全版本、端口:11211)
  8. zeromq不需要消息服务器,ZeroMQ发布订阅TCP丢弃消息订阅服务器失败
  9. 2D Perlin噪点
  10. (6)Linux进程调度-实时调度器
  11. CPU 架构 —— ARM 架构
  12. android init重启service(进程)
  13. python撤回快捷键大全_Python基础之PyCharm快捷键大全
  14. 《天勤数据结构》笔记——顺序栈和链栈及其代码实现(C/C++)
  15. 几个好用的资源下载网址
  16. 太阳能计算机屏幕是什么材质,电脑显示器表面是什么材质的 什么是液晶玻璃...
  17. HPE 3PAR StoreServ存储系统连接解决方案
  18. 模仿百思不得姐项目笔记
  19. 聚美优品根据ID取商品详情 API
  20. 虚幻4场景渲染源码分析概述

热门文章

  1. webstrom Certificate validation failed
  2. 【剑指offer-Java版】17合并两个排序链表
  3. Eclipse中安装HibernateTools插件
  4. Worker启动Executor源码
  5. Paint滤镜效果实现
  6. 【Android基础】动画
  7. (017)java后台开发之客户端通过HTTP获取接口Json数据
  8. (0030) iOS 开发之跳转之转场动画
  9. InetAddress类和InetSocketAddress的使用
  10. python CST中国标准时间格式转换