js中常见的几种深拷贝方法 |
您所在的位置:网站首页 › js中深拷贝的方法 › js中常见的几种深拷贝方法 |
文章目录
使用递归方式进行深拷贝通过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 |