浅拷贝
拷贝的是其引用,指向的是同一个内存地址,所以不管变动哪一个都会跟着改变;
eg:A和B住一间屋子,不管A还是B改变房子的样子,他们的屋子都发生了变化;
var a=[2,8,3];
var b=a;
a[0]=1;
console.log(a,b); // a=[1,8,3] b=[1,8,3]
b[0]=5;
console.log(a,b); // a=[5,8,3] b=[5,8,3]
深拷贝
拷贝的是其对象本身,为独立的个体,互不影响;
eg:A和B分别住两间一样的屋子,不管A还是B改变自己屋子的样子都互不影响;
var a=[2,8,3];
var b=a.slice();
a[0]=1;
console.log(a,b); // a=[1,8,3] b=[2,8,3]
b[0]=5;
console.log(a,b); // a=[1,8,3] b=[5,8,3]
深拷贝的方法
一.Array
1.slice()
var arr1 = [1, 2], arr2 = arr1.slice();
console.log(arr1); //[1, 2]
console.log(arr2); //[1, 2]
arr2[0] = 3; //修改arr2
console.log(arr1); //[1, 2]
console.log(arr2); //[3, 2]
var arr1 = [1, 2, [3, 4]], arr2 = arr1.slice();
console.log(arr1); //[1, 2, [3, 4]]
console.log(arr2); //[1, 2, [3, 4]]
arr2[2][1] = 5;
console.log(arr1); //[1, 2, [3, 5]]
console.log(arr2); //[1, 2, [3, 5]]
arr2又改变了arr1,看来slice()只能实现一维数组的深拷贝。
具备同等特性的还有:concat、Array.from() 。
二.Object
1.Object.assign()也只能实现一维对象的深拷贝。
var obj1 = {x: 1, y: 2}, obj2 = Object.assign({}, obj1);
console.log(obj1) //{x: 1, y: 2}
console.log(obj2) //{x: 1, y: 2}
obj2.x = 2; //修改obj2.x
console.log(obj1) //{x: 1, y: 2}
console.log(obj2) //{x: 2, y: 2}
var obj1 = {
x: 1,
y: {
m: 1
}
};
var obj2 = Object.assign({}, obj1);
console.log(obj1) //{x: 1, y: {m: 1}}
console.log(obj2) //{x: 1, y: {m: 1}}
obj2.y.m = 2; //修改obj2.y.m
console.log(obj1) //{x: 1, y: {m: 2}}
console.log(obj2) //{x: 2, y: {m: 2}}
2.JSON.parse(JSON.stringify(obj))
JSON.parse(JSON.stringify(obj))的使用也是有局限性的,不能深拷贝含有undefined、function、symbol值的对象,
不过JSON.parse(JSON.stringify(obj))简单粗暴,已经满足90%的使用场景了。
var a = {age:1,name:'ccy',info:{address:'wuhan',interest:'playCards'}};
var b = JSON.parse(JSON.stringify(a));
a.info.address = 'shenzhen';
console.log(a.info,b.info);
/*
{address:'shenzhen',interest:'playCards'}
{address:'wuhan',interest:'playCards'}
*/
3.递归
function deep(obj) {
// for(key in this.kkk){
// console.log(typeof this.kkk[key],"55555555555555555555555",this.kkk[key],this.kkk[key]==='object')
// }
//判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝
var objClone = Array.isArray(obj) ? [] : {};
console.log(objClone,"99999999999",obj,typeof obj,"000000",obj && typeof obj === "object","5555555")
//进行深拷贝的不能为空,并且是对象或者是
if (obj && typeof obj === "object") {
for (key in obj) {
console.log(key,"434343",obj,"0000000000000",obj.hasOwnProperty(key))
// 判断自身属性是否存在 obj.hasOwnProperty()
// 判断obj是否存在key属性
if (obj.hasOwnProperty(key)) {
if (obj[key] && typeof obj[key] === "object") {
objClone[key] = deep(obj[key]);
} else {
objClone[key] = obj[key];
}
}
}
}
return objClone;
};