小记~
一、什么是深拷贝、浅拷贝?
const A = [1,2,3,4,[5,6]]
浅拷贝:也就是拷贝A对象里面的数据,但是不拷贝A对象里面的子对象
深拷贝:会克隆出一个对象,数据相同,但是引用地址不同(就是拷贝A对象里面的数据,而且拷贝它里面的子对象)
二、深拷贝和浅拷贝有什么区别?
三、深拷贝和浅拷贝如何实现?
浅拷贝:
- arr.concat()
test1() {
const arr = [1, 2, 3, 4, [5, 6]];
const copy = arr.concat();
// 改变基本数据类型,不会改变原始值
copy[0] = 99;
console.log("改变基本数据类型:", arr);
// 改变引用类型,改变原始值
copy[4][1] = 77;
console.log("改变引用类型:", arr);
},
- Object.assign({}, obj1)
test2() {
const obj1 = { x: 1, y: 2 };
const obj2 = Object.assign({}, obj1);
obj2.x = 22; //修改obj2.x,改变对象中的基本类型值
console.log("obj1:", obj1);
console.log("obj2:", obj2);
const obj3 = {
x: 33,
y: {
m: 33,
},
};
const obj4 = Object.assign({}, obj3);
obj4.y.m = 44;
console.log("浅拷贝:");
console.log("obj3:", obj3); //{x:33,y:{ m:44}};
console.log("obj4:", obj4); //{x:33,y:{ m:44}};
},
深拷贝:
- JSON.parse(JSON.stringify(obj1))
test3() {
const obj1 = {
x: 1,
y: {
m: 1,
},
};
const obj2 = JSON.parse(JSON.stringify(obj1));
console.log("深拷贝:");
console.log("obj1:", obj1);//{x:1,y:{ m:1}};
console.log("obj2:", obj2);//{x:1,y:{ m:1}};
obj2.y.m = 2;
console.log("修改obj2.y.m:");
console.log("obj1:", obj1);//{x:1,y:{ m:1}};
console.log("obj2:", obj2);//{x:1,y:{ m:2}};
}
2.递归
test4() {
const obj1 = {
x: {
m: 1,
},
y: undefined,
z: function add(z1, z2) {
return z1 + z2;
},
a: Symbol("foo"),
};
console.log("采用递归方式进行深拷贝:");
const obj2 = this.deepCopy(obj1);
obj2.x.m = 2;
console.log(obj1);
console.log(obj2);
},
// 深拷贝-递归
deepCopy(obj) {
// 创建一个新对象
let result = {};
let keys = Object.keys(obj),
key = null,
temp = null;
for (let i = 0; i < keys.length; i++) {
key = keys[i];
temp = obj[key];
// 如果字段的值是一个对象则递归操作
if (temp && typeof temp === "object") {
result[key] = this.deepCopy(temp);
} else {
result[key] = temp;
}
}
return result;
},
四、使用JSON.parse(JSON.stringfy(obj))深拷贝有什么缺点?
缺点:
- obj里面有时间对象,采用JSON.parse(JSON.stringify(obj1))深拷贝之后,时间只是字符串形式,而不是时间对象
test3(){
var obj3 = {
name: "a",
date: [new Date(1536627600000), new Date(1540047600000)],
};
var copyedObj3 = JSON.parse(JSON.stringify(obj3));
console.log(copyedObj3);//{name: "a",date: (2) ["2018-09-11T01:00:00.000Z", "2018-10-20T15:00:00.000Z"]}
}
2.如果obj里面有正则RegExp、Error对象,则序列化的结果将只得到空对象
test5(){
const obj5 = {
name: "a",
date: new RegExp("\\w+"),
};
const copyedObj5 = JSON.parse(JSON.stringify(obj5));
console.log("obj5:", obj5);//{name: "a",date: /\w+/}
console.log("copyedObj5:", copyedObj5);//{name: "a",date: {}}
}
3.如果obj里面有函数、undefined,则序列化的结果会把函数或undefined丢失
test6(){
const obj6 = {
name: "a",
date: function() {
console.log("我是obj里面的函数");
},
};
const copyedObj6 = JSON.parse(JSON.stringify(obj6));
console.log("obj6:", obj6);//{name: "a",date:f date()
console.log("copyedObj6:", copyedObj6);//{name: "a"}
const obj7 = {
name: "a",
date: undefined,
};
const copyedObj7 = JSON.parse(JSON.stringify(obj7));
console.log("obj7:", obj7);//{name: "a", date: undefined}
console.log("copyedObj7:", copyedObj7);//{name: "a"}
}
- 如果obj里面有NaN、Infinity和-Infinity,则序列化的结果会变成null
test8(){
const obj8 = {
name: "a",
date: NaN,
};
const copyedObj8 = JSON.parse(JSON.stringify(obj8));
console.log("obj8:", obj8);//{name: "a", date: NaN}
console.log("copyedObj8:", copyedObj8);{name: "a", date: null}
}
五、深拷贝和浅拷贝涉及到其他知识:
1、什么是JS的基本数据类型和引用类型?有什么区别?
2、什么是堆和栈?有什么区别?
3、堆和栈的数据结构是什么样的?
4、如何理解什么是传值,什么是传址?
5、堆和栈的图示改怎么画?如:Var user = {name:'张三'}
网友评论