概念
浅拷贝创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。
深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象。
浅拷贝
let obj = {
id: 1,
name: 'uzi',
msg: {
age: 5
}
}
let a = {};
for(let b in obj) { // 浅拷贝, msg只拷贝了引用
a[b] = obj[b];
}
a.msg.age = 18; // obj.msg.age 也变为 18;
// ----------------------------------------------
Object.assign(a, obj); // 复制对象,也是浅拷贝
// ---------------------------------------------
// 浅拷贝方法
function shallowCopy(source) {
var target = {};
for(var i in source) {
if (source.hasOwnProperty(i)) {
target[i] = source[i];
}
}
return target;
}
// -------------------------------------
// 展开运算符
let a = {...obj}
深拷贝
利用递归的方式实现深拷贝
// 乞丐版
function deepCopy(newObj, oldObj) {
for(let k in oldObj) {
// 判断属性值为什么类型
let item = oldObj[k];
if(item instanceof Array) { // 类型为数组时, 数组也是Object,所以写前面
newObj[k] = [];
deepCopy(newObj[k], item);
} else if(item instanceof Object) { // 类型为对象
newObj[k] = {};
deepCopy(newObj[k], item);
} else { // 简单数据类型
newObj[k] = item;
}
}
}
完整优化参考如何写出一个惊艳面试官的深拷贝?
JSON.parse
let obj = {
id: 1,
name: 'uzi',
msg: {
age: 5
}
}
let obj1 = JSON.parse(JSON.stringify(obj));
这种方法虽然可以实现数组或对象深拷贝,但不能处理函数和正则,因为在使用JSON.stringify和JSON.parse处理后,得到的正则就不再是正则(变为空对象),得到的函数就不再是函数(变为null)。
函数库lodash的_.cloneDeep方法
jQuery.extend()方法
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!