js中常见的几种深拷贝方法

您所在的位置:网站首页 js中深拷贝的方法 js中常见的几种深拷贝方法

js中常见的几种深拷贝方法

2023-08-23 15:23| 来源: 网络整理| 查看: 265

文章目录 使用递归方式进行深拷贝通过JSON序列化实现深拷贝lodash函数库实现深拷贝使用jq(extend)方法实现深拷贝其他补充slice()和concat()object.assign() 总结

使用递归方式进行深拷贝 let deepClone = (initalObj) => { const obj = {}; if(typeof initalObj !== 'object'){ return initalObj } for (const key in initalObj) { if (typeof initalObj[key] === 'object') { //对数组特殊处理 if (Array.isArray(initalObj[key])) { //用map方法返回新数组,将数组中的元素递归 obj[key] = initalObj[key].map(item => this.deepClone(item)) } else { //递归返回新的对象 obj[key] = this.deepClone(initalObj[key]); } } else if (typeof initalObj[key] === 'function') { //返回新函数 obj[key] = initalObj[key].bind(obj); } else { //基本类型直接返回 obj[key] = initalObj[key]; } } return obj; } const obj = { a: 1, b: {}, c: { d: {}, g: () => {} }, e: () =>{}, f: function () {} } const newObj = deepClone(obj); newObj.a === obj.a //true newObj.b === obj.b //false newObj.c === obj .false //false newObj.c.d === obj.c.d //false newObj.c.g === obj.c.g //false newObj.e === obj.e //false newObj.f === obj.f //false 递归运行效率低,次数过多的话容易造成栈溢出。比较常用!兼容性好! 通过JSON序列化实现深拷贝

序列化后再反序列化。

function Clone(obj) { var Copyobj = JSON.stringify(obj), //json字符串转json对象 objClone = JSON.parse(Copyobj); return objClone; }

注意,这种方法容易出很多问题,实际并不常用!

如果obj里有RegExp、Error对象,则序列化的结果将只得到空对象

如果obj里面有时间对象,则JSON.stringify后再JSON.parse的结果,时间将只是字符串的形式。而不是时间对象

如果obj里有函数,undefined,则序列化的结果会把函数或 undefined丢失

如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null

无法处理function,无法处理循环引用对象

lodash函数库实现深拷贝 var abj={ a:1, b:2 } var copyobj = lodash.cloneDeep(abj)

这个没啥好说的,就是调用库函数罢了,原理和第一个一样。

使用jq(extend)方法实现深拷贝 var obj= { a:10, b:function (){ console.log(this.a) } }; var newObj = $.extend(true,{},obj);

这个也没啥好说的,就是调用库函数…啊这

其他补充 slice()和concat()

使用slice、concat方法并不是真正的深拷贝!

它们只会复制第一层,而到了第二层及其之后,只会复制引用地址了!

使用方法如下:

对于数组类型,可以使用slice(start, end)方法,返回一个新的数组。var arr1 = arr.slice(0);数组类型还可以使用concat()方法,var arr1 = arr.concat(); object.assign() var obj1 = { a: 0 , b: { c: 0}}; var obj2 = Object.assign({}, obj1);

当对象中只有一级属性,没有二级属性的时候,此方法为深拷贝

如果是有多层嵌套呢?

var obj1 = { a: 1, b: 2, c: ['a','b','c'] } var obj2 = Object.assign({}, obj1); obj2.c[1] = 5; console.log(obj1.c); // ["a", 5, "c"] console.log(obj2.c); // ["a", 5, "c"]

可以看到对于一层对象来说是没有任何问题的,但是如果对象的属性对应的是其它的引用类型的话,还是只拷贝了引用,修改的话还是会有问题。

所以可知,对象中有对象的时候,此方法在二级属性以后就是浅拷贝。

总结

从原理上来说,只有以下两种方法是无论有多少层嵌套都能实现真正的深拷贝。

自定义递归方法json序列化

但是json序列化容易出bug,所以实际编写工具函数时,都会用第一种方法。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3