js deep clone 深克隆
首先,值的拷贝,通常有三种方式,由于基本类型与引用类型在内存中存储位置和存储方式的不同,导致了以下三种概念的衍生:
- = 赋值:多个指针指向的是同一个堆中的地址,所以相互有影响;
- 浅拷贝:在堆中重新创建内存,拷贝前后基本数据类型不受影响,但只拷贝一层,无法拷贝子对象;所以改变浅拷贝得到的对象中的引用类型时,原始数据会受到影响;例如数组的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 深克隆相关推荐
- 深拷贝(deep clone)与浅拷贝(shallow clone)
深拷贝(deep clone)与浅拷贝(shallow clone) 浅复制(浅克隆):被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复 ...
- 小和尚学习 - JS shallow clone 和 deep clone
决定一个人的一生,以及整个命运的,只是一瞬之间.--歌德 目录 浅克隆 深克隆 丐中丐版 大众版 升级版 终极版 今天,小和尚和大伙聊聊一个面试家常菜:请手写一个 JS 深克隆. 在正式开始前,先了解 ...
- java deep clone util_Java Clone深拷贝与浅拷贝的两种实现方法
1.首先,你要知道怎么实现克隆:实现Cloneable接口,在bean里面重写clone()方法,权限为public. 2.其次,你要大概知道什么是地址传递,什么是值传递. 3.最后,你要知道你为什么 ...
- java deep clone util_实现对象深度克隆(deepClone)的三种方案
转:http://www.cnblogs.com/wangzhichao/archive/2013/04/11/3014419.html 方案一:利用现代浏览器支持的JSON对象做一次中转,实现深度克 ...
- java中的深浅克隆
假设有一个对象object,在某处又需要一个跟object一样的实例object2,强调的是object和object2是两个独立的实例,只是在开始的时候,他们是具有相同状态的(属性字段的值都相同). ...
- JS 开发常用工具函数
本文原载于SegmentFault专栏 作者:hfhan 整理编辑:SegmentFault 1.isStatic:检测数据是不是除了symbol外的原始数据 function isStatic(va ...
- (转载)jQuery 1.6 源码学习(一)——core.js[1]之基本架构
在网上下了一个jQuery 1.2.6的源码分析教程,看得似懂非懂,于是还是去github上下载源码,然后慢慢看源代码学习,首先来说说core.js这个核心文件吧. jQuery整体的基本架构说起来也 ...
- 国庆假 的CSS +JS 学习笔记
1.左右两列定宽,中间自适应, 6. 一个div 中,放三个div ,其中左边和右边是150px,中间div 自适应宽度. left center right .content{ background ...
- 学习 jQuery 源码整体架构,打造属于自己的 js 类库
虽然现在基本不怎么使用 jQuery了,但 jQuery流行 10多年的 JS库,还是有必要学习它的源码的.也可以学着打造属于自己的 js类库,求职面试时可以增色不少. 本文章学习的是 v3.4.1版 ...
最新文章
- Bytom BIP-32协议和BIP-44协议解读
- 「AHOI / HNOI2018」转盘 解题报告
- Oracle免安装绿色版-PLSQL连接报12154
- Windows进程与线程学习笔记(三)—— KPCR
- iframe_demo实例:消息发送(PHP版本)
- Scala学习(十二)高阶函数
- Memcached未授权访问漏洞记录(CVE-2013-7239、危害级别全版本、端口:11211)
- zeromq不需要消息服务器,ZeroMQ发布订阅TCP丢弃消息订阅服务器失败
- 2D Perlin噪点
- (6)Linux进程调度-实时调度器
- CPU 架构 —— ARM 架构
- android init重启service(进程)
- python撤回快捷键大全_Python基础之PyCharm快捷键大全
- 《天勤数据结构》笔记——顺序栈和链栈及其代码实现(C/C++)
- 几个好用的资源下载网址
- 太阳能计算机屏幕是什么材质,电脑显示器表面是什么材质的 什么是液晶玻璃...
- HPE 3PAR StoreServ存储系统连接解决方案
- 模仿百思不得姐项目笔记
- 聚美优品根据ID取商品详情 API
- 虚幻4场景渲染源码分析概述