JavaScript中深拷贝实现
/**
* 获取满足条件的数组中的第一个元素
* @param {Array} list 将要筛选的数组
* @param {Function} f 用来过滤的函数
*/
function find(list, f) {
return list.filter(f)[0]
}
/**
* 深拷贝对象,同时考虑到了循环引用的情况
* 缓存了所有的嵌套对象和它的拷贝
* 如果检测到循环引用,返回拷贝,防止了无限循环
* @param {Object} obj 需要拷贝的对象
* @param {Array} cache 用来判断是否循环引用,存储对象以及对象的拷贝
*/
function deepCopy(obj, cache = []) {
// 为空或者不是对象则返回原 obj
if (obj === null || typeof obj !== 'object') {
return obj
} // 若是循环结构,则返回之前对象的 copy,而不是引用
const hit = find(cache, c => c.original === obj)
if (hit) {
return hit.copy
} const copy = Array.isArray(obj) ? [] : {}
// 将 copy 放入 cache 中
// 我们可能在递归中引用 copy
cache.push({
original: obj,
copy
}) Object.keys(obj).forEach(key => {
copy[key] = deepCopy(obj[key], cache)
}) return copy
}
应用
const original = {
a: 1,
b: 'string',
c: true,
d: null,
e: undefined
}
const copy = deepCopy(original)
console.log('copy === original :', copy === original)
// copy === original : false
console.log('copy :', JSON.stringify(copy, null, 2))
// copy : {
// "a": 1,
// "b": "string",
// "c": true,
// "d": null
// }
2、嵌套例子:
const original = {
a: {
b: 1,
c: [
2,
3,
{
d: 4
}
]
}
}
const copy = deepCopy(original)
console.log('copy === original :', copy === original)
// copy === original : false
console.log('copy :', JSON.stringify(copy, null, 2))
// copy : {
// "a": {
// "b": 1,
// "c": [
// 2,
// 3,
// {
// "d": 4
// }
// ]
// }
// }
const original = {
a: 1
}
original.circularExample = original const copy = deepCopy(original)
console.log('copy === original :', copy === original)
// copy === original : false
console.log('copy :', copy)
// 这里循环引用不可使用 JSON.stringify 来转换,会报错
// copy : { a: 1, circularExample: [Circular] }
JavaScript中深拷贝实现的更多相关文章
- Javascript中的深拷贝和浅拷贝
var obj = { a:1, arr: [1,2] }; var obj1 = obj; //浅复制 var obj2 = deepCopy(obj); //深复制 javascript中创建对象 ...
- Javascript中的浅拷贝和深拷贝
很多开发语言中都有浅拷贝和深拷贝的说法,这里简单区分一下它们在Javascript中的区别,以及jQuery中深拷贝的实现. 在谈浅拷贝和深拷贝之前,先要屡清楚Javascript中的按值访问和按引用 ...
- (译文)JavaScript基础——JavaScript中的深拷贝
在JavaScript中如何拷贝一个对象? 通过引用调用 function mutate(obj) { obj.a = true; } const obj = {a: false}; mutate(o ...
- javascript中的深拷贝与浅拷贝
javascript中的深拷贝与浅拷贝 基础概念 在了解深拷贝与浅拷贝的时候需要先了解一些基础知识 核心知识点之 堆与栈 栈(stack)为自动分配的内存空间,它由系统自动释放: 堆(heap)则是动 ...
- 深入理解JavaScript中的堆与栈 、浅拷贝与深拷贝
JavaScript中的浅拷贝与深拷贝 学了这么长时间的JavaScript想必大家对浅拷贝和深拷贝还不太熟悉吧,今天在项目中既然用到了,早晚也要理清一下思路了,在了解之前,我们还是先从JavaSc ...
- javascript中的堆栈、深拷贝和浅拷贝、闭包
堆栈 在javascript中,堆内存是用来存放引用类型的空间环境 而栈内存,是存储基本类型和指定代码的环境 在对象中的属性名具有唯一性,数字属性名=字符串属性名,但是在测试的时候你会发现,好像所有属 ...
- JavaScript中的深拷贝和浅拷贝!【有错误】还未修改!请逛其他园子!
JavaScript中的深拷贝和浅拷贝! 浅拷贝 1.浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用.{也就是拷贝的是地址!简而言之就是在新的对象中修改深层次的值也会影响原来的对象!} // 2.深 ...
- JavaScript 中的数据类型
Javascript中的数据类型有以下几种情况: 基本类型:string,number,boolean 特殊类型:undefined,null 引用类型:Object,Function,Date,Ar ...
- javascript 中继承实现方式归纳
转载自:http://sentsin.com/web/1109.html 不同于基于类的编程语言,如 C++ 和 Java,javascript 中的继承方式是基于原型的.同时由于 javascrip ...
随机推荐
- Java文件拷贝方式
原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11444284.html 利用java.io类库,直接为源文件构建一个FileInputStream读取 ...
- Scala(一)基础
OOP 面向对象编程 AOP 面向切面编程 FP 函数式编程 编程语言都要定义变量,一些代码是用来注释的,变量和变量之间有一些关系,要做一些运算,运算离不开流程控制,进行运算的数据往往来自数据结构,最 ...
- 二叉堆 与 PriorityQueue
堆在存储器中的表示是数组,堆只是一个概念上的表示.堆的同一节点的左右子节点都没有规律. 堆适合优先级队列(默认排列顺序是升序排列,快速插入与删除最大/最小值). 数组与堆 堆(完全二叉树)(构造大顶堆 ...
- js手机滚屏效果
原文地址:https://github.com/yanhaijing/zepto.fullpage 第一步:基于移动端的浏览体验,在头部添加浏览器渲染的分辨率 <meta name=" ...
- DNS域名服务器的搭建
父域的DNS(svr7): 可以解析父域名下保存的域名地址,即解析.tedu.cn下的域名 一.安装软件包bind.bind-chroot bind是DNS解析服务需要用到的服务软件包,bind- ...
- NX二次开发CreateDialog函数在UI.hxx文件和WinUser.h中的冲突【转载】
文章出自https://blog.csdn.net/qq_41843732/article/details/91422764 在UG二次开发中,若使用MFC库,一旦加上#include<Afx. ...
- Angularjs 1.3在页面中输出带Html标记的文本
如何Angularjs1.3在页面中输出带Html标记的文本 基于安全考虑,Angularjs不允许用ng-bind或者{{}}的方法输出html文本. 在实际的应用中,比如信息管理系统,用在线编辑器 ...
- HTML5自定义属性的设置与获取
<div id="box" aaa="bbb" data-info="hello"></div> <body& ...
- IceCTF-Matrix
解题思路: 参考了鸽子小姐姐的脚本:https://zhuanlan.zhihu.com/p/22678856 具体题目就不贴了. 题目中提示将问题图像化,猜测是将这些16进制数转化为图像,尝试将16 ...
- this和super差异
<三> this和super差异 1)super(参数):调用基类中的某一个构造函数(应该为构造函数中的第一条语句) 2)this(参数):调用本类中另一种形成的构造函数(应该为构造函数中 ...