https://www.cnblogs.com/echolun/p/7889848.html
https://www.jianshu.com/p/cf1e9d7e94fb
简介
- 简单的来说,有个对象a, b复制了a, 修改b会影响到a就是浅拷贝,不会影响则是深拷贝
- js中有
基本数据类型
,引用数据类型
; 他们涉及到堆栈内存
;
基本数据类型
的键值都在栈
,复制时会开辟新的空间;
引用数据数据类型
的键在栈
中,值在堆
里面,但是栈内存
会提供一个引用的地址指向堆内存
中的值;b = a 拷贝
时只复制到栈
中的地址,而非堆
中的值,所以都指向堆
中的同一个值
递归实现深拷贝
- hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)。
// 递归实现深拷贝
// 非最佳实现
function deepCopy(obj) {
// 原对象是数组则先初始化为数组,否则初始化为对象
let objCopy = Array.isArray(obj) ? [] : {};
// 判断obj是否为引用数据类型
if (obj && typeof obj === "object") {
for (key in obj) {
let prop = obj[key];
if (prop == obj) {
//避免相互引用造成死循环,如obj.a=obj
continue;
}
// 判断obj是否有指定的键或者属性
if (obj.hasOwnProperty(key)) {
// 判断obj子元素是否为引用数据类型,是则递归赋值
if (obj[key] && typeof obj[key] === "object") {
objCopy[key] = deepCopy(obj[key]);
} else {
// 否则简单复制
objCopy[key] = obj[key];
}
}
}
}
return objCopy;
}
let a = [1, 2, 3, [4, 5]];
let b = deepCopy(a);
b[3][0] = 1;
console.log("a", a);
console.log("b", b);
![](https://img.haomeiwen.com/i22548971/de93d37b90e9ae66.png)
使用JSON.stringify和JSON.parse实现深拷贝
// 使用JSON.stringify和JSON.parse实现深拷贝
function deepCopy(obj) {
let _obj = JSON.stringify(obj)
let objCopy = JSON.parse(_obj)
return objCopy
}
let a = [1, 2, 3, 4, [5, 6]];
let b = deepCopy(a);
b[4][0] = 1;
console.log("a", a);
console.log("b", b);
![](https://img.haomeiwen.com/i22548971/e621fb356ef0e70f.png)
- 但是它会抛弃对象的constructor,深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成Object;这种方法能正确处理的对象只有 Number, String, Boolean, Array, 扁平对象,也就是说,只有可以转成JSON格式的对象才可以这样用,像function没办法转成JSON;
使用lodash
的_.cloneDeep
深拷贝
let _ = require('lodash')
let obj1 = {
a: 1,
b: {
bb: {
bbb: 2,
},
},
c: 3,
}
let obj2 = _.cloneDeep(obj1)
obj2.b.bb.bbb = 22
console.log('obj1',obj1);
console.log('obj2',obj2);
网友评论