浅拷贝只是增加了一个指针,指向已存在的内存地址。
深拷贝增加一个指针,并开辟一个新的内存空间,使这个指针指向新的内存地址。
假设B复制了A,修改A时看B是否发生了变化,如果发生了变化,说明是浅拷贝,拿人手短(修改堆内存中的同一个值); 如果B没有变化说明是深拷贝,自食其力。(修改堆内存中的不同值)
浅拷贝实现:
var a = [1, 2, 3, 4, 5];
var b = a;
a[0] = 2
console.log(a);
console.log(b);
//因为b浅拷贝a, ab指向同一个内存地址(堆内存中存的值)
//b会随着a的变化而变化
//[2, 2, 3, 4, 5]
//[2, 2, 3, 4, 5]
浅拷贝示意图

深拷贝示意图

实现数组深拷贝的一些方法:
1.使用es6
var a=[1,2,3]
var b=[...a];
b.push(4);
console.log(b);//1,2,3,4
console.log(a)//1,2,3
2.使用concat()方法
var a=[1,2,3]
var c=[];
var b=c.concat(a);
b.push(4);
console.log(b);//1,2,3,4
console.log(a)//1,2,3
3.使用slice()方法
var a=[1,2,3]
var b=a.slice(0);
b.push(4);
console.log(b);//1,2,3,4
console.log(a)//1,2,3
4.ES6的Object.assign()方法
var obj = {
name: 'JK',
job: '前端开发工程师'
}
var copyObj = Object.assign({}, obj);
copyObj.name = 'JKWu';
console.log(obj); // {name: "Jk", job: "学生"}
console.log(copyObj); // {name: "JKWu", job: "前端开发工程师"}
复杂深拷贝(对象或者数组)
1.使用JSON对象的stringify和parse方法
var a=[1,2,3]
var b=JSON.parse(JSON.stringify(a));
b.push(4);
console.log(b);//1,2,3,4
console.log(a)//1,2,3
JSON.parse() 方法用于将一个 JSON 字符串转换为对象--(反序列化)
JSON.stringify() 方法是将一个JavaScript值(对象或者数组)转换为一个 JSON字符串--(序列化)
序列化的缺点:
1.不支持基本数据类型的undefined,序列化后将其省略
2.不支持函数
3.Nan,Infinity序列化的结果是null
2.使用递归
function deep(obj) {
//判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝
var objClone = Array.isArray(obj) ? [] : {};
//进行深拷贝的不能为空,并且是对象或者是
if (obj && typeof obj === "object") {
for (key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key] && typeof obj[key] === "object") {
objClone[key] = deep(obj[key]);
} else {
objClone[key] = obj[key];
}
}
}
}
return objClone;
}