- 浅拷贝:只会复制对象的第一层数据
- 深拷贝:不仅仅会复制第一层的数据,如果里面还有对象,会继续进行复制,直到复制到全是基本数据类型为止
简单来说,浅拷贝是都指向同一块内存区块,而深拷贝则是另外开辟了一块区域
例如,下面就是浅拷贝:
let arr = [1,2,3,4];
let arr2 = arr;
arr2.push(5);
console.log(arr); // [1, 2, 3, 4, 5]
console.log(arr2); // [1, 2, 3, 4, 5]
对深拷贝来说,有以下的方法:
1. 深拷贝的简单方法:
- 对数组来说:
let arr = [1,2,3,4];
let arr2 = [];
for(let i=0;i<arr.length;i++){
arr2[i] = arr[i];
}
arr2.push(5);
console.log(arr); // [1, 2, 3, 4]
console.log(arr2); // [1, 2, 3, 4, 5]
- 对对象来说(for..in):
let obj = {
name:"haha",
age:18
}
let obj2 = {};
for(var attr in obj){
obj2[attr] = obj[attr]
}
obj2.name = 'hehe';
console.log(obj); // {name: "haha", age: 18}
console.log(obj2); // {name: "hehe", age: 18}
2. 转成 JSON 再转回来
用JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象。
let arr = [1,2,3,4];
let arr2 = JSON.parse(JSON.stringify(arr));
// JSON.parse() 用于将一个 JSON 字符串转换为 JavaScript 对象。
// JSON.stringify() 用于将 JavaScript 值转换为 JSON 字符串。
arr2.push(5);
console.log(arr); // [1, 2, 3, 4, 5]
console.log(arr2); // [1, 2, 3, 4, 5]
3. 深拷贝的es6方法:Object.assign()
let obj = {
name:"haha",
age:18
}
let obj2 = {};
Object.assign(obj2,obj);
obj2.name = 'hehe';
console.log(obj); // {name: "haha", age: 18}
console.log(obj2); // {name: "hehe", age: 18}
4. 深拷贝的方法封装:
但是,对于下面的例子(包含多层对象),不能用Object.assign()
let arr = [1,2,3,4,[5],{}];
let arr2 = Object.assign([],arr);
arr2[4].push(6);
console.log(arr) // [1, 2, 3, 4, [5,6], {…}]
console.log(arr2) // [1, 2, 3, 4, [5,6], {…}]
所以,这里封装了一个深拷贝函数deepClone
let arr = [1,2,3,4,[5],{}];
let arr2 = deepClone(arr);
arr2[4].push(6);
function deepClone(obj){ //深度克隆
let o = obj.push?[]:{};
for(let attr in obj){
//值为复合类型
if(typeof obj[attr] === 'object' && obj[attr]!=null){
o[attr] = deepClone(obj[attr]);
}else{
o[attr] = obj[attr];
}
}
return o;
}
console.log(arr) // [1, 2, 3, 4, [5], {…}]
console.log(arr2) // [1, 2, 3, 4, [5,6], {…}]