就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,如果B没变,那就是深拷贝
实现浅拷贝的方法
1.Object.assign方法可以实现浅拷贝和深拷贝
一、Object.assign直接拷贝是浅拷贝
var obj = {
a: 1,
b: 2
}
var obj1 = Object.assign(obj);
obj1.a = 3;
console.log(obj) // {a:3,b:2} 改变原数据-浅拷贝
二、如果对象的value是基本类型的话,也可以用Object.assign来实现深拷贝,但是要把它赋值给一个空对象{}Object.assign()
进行的是浅拷贝,拷贝的是对象的属性的引用,而不是对象本身
var obj = { a: {a: "aa", b: 1} };
var obj1 = Object.assign({}, obj);
obj1.a.a = "bb";
console.log(obj.a.a); // bb
注意:当object只有一层的时候,是深拷贝
let obj = {
a: 1,
b: 2
};
let obj2 = Object.assign({},obj);
obj2.a = '3';
console.log(obj);//{a:1,b:2} 没有改变--深拷贝不影响原数据
2.直接用=赋值
let a=[0,1,2,3,4],
b=a;
console.log(a===b); // true
a[0]=1;
console.log(a,b); // [1,1,2,3,4] [1,1,2,3,4]
3.for···in只循环第一层
// 只复制第一层的浅拷贝
function copyOne(obj1) {
var obj2 = Array.isArray(obj1) ? [] : {};
for (let i in obj1) {
obj2[i] = obj1[i];
}
return obj2;
}
var obj1 = {
a: 1,
b: 2,
c: {
d: 3
}
}
var obj2 = copyOne(obj1);
obj2.a = 3;
obj2.c.d = 4;
console.log(obj1.a, obj2.a); // 1 3
console.log(obj1.c.d, obj2.c.d); // 4 4
4.concat() / slice()
let arr = [1, 3, {
a: '1'
}];
let arr2=arr.concat(); 或者 let arr2=arr.slice()
arr2[2].a = '2';
console.log(arr,arr2);
结果如下:Array的slice和concat方法不修改原数组,只会返回一个浅拷贝了原数组中的元素的一个新数组。 该元素是个对象引用(不是实际的对象),slice 会拷贝这个对象引用到新的数组里。两个对象引用都引用了同一个对象。如果被引用的对象发生改变,则新的和原来的数组中的这个元素也会发生改变---浅拷贝
let arr = [1, 3, {
a: '1'
}];
let arr3 = arr.slice();
arr3[1] = 2
console.log(arr,arr3);
结果如下: 对于字符串String、数字Number及布尔值Boolean,slice 会拷贝这些值到新的数组里,在新数组里修改时,将不会影响另一个数组----深拷贝
实现深拷贝的方法
1.通过JSON对象实现
let arr = [1, 3, {
a: '1'
}];
let arr2 = JSON.parse(JSON.stringify(arr));
arr2[2].a = '2';
console.log(arr, arr4)
结果如下
原理: 用JSON.stringify将对象转成JSON字符串,再用JSON.parse()把字符串解析成对象,一去一来,新的对象产生了,而且对象会开辟新的栈,实现深拷贝
缺点: 可以实现数组或对象深拷贝,但不能处理函数,无法实现对对象中方法的深拷贝,会显示为undefined
let arr = [1, 3, {
a: '1'
},function(){}];
let arr4 = JSON.parse(JSON.stringify(arr));
arr4[2].a = '2';
console.log(arr, arr4);
结果如下:因为 JSON.stringify()
方法是将一个JavaScript值(对象或者数组)转换为一个 JSON字符串,不能接受函数
2.lodash函数库实现深拷贝
该函数库也有提供 _.cloneDeep
用来做 Deep Copy
var _ = require('lodash');
var obj1 = {
a: 1,
b: { e: { f: 1 } },
c: [1, 2, 3]
};
var obj2 = _.cloneDeep(obj1);
console.log(obj1.b.e === obj2.b.e); // false