深拷贝和浅拷贝的核心是数据类型在内存中存储的地方
基本数据类型
基本数据类型的值都是存储在栈中的,操作后返回的都是新的值。
我们定义一个基本数据类型
let str1 = 1;
// 把str1进行一个拷贝赋值
let str2 = str1;
赋值前
赋值后
它们在栈内存中是独立存储的,赋值后互不影响
引用数据类型
引用数据类型的数据源放在堆内存中,通过指针指向数据源,指向数据源的指针是放在栈内存中。引用数据类型的拷贝是将指向数据源的指针进行一个拷贝赋值
let obj = {name: 'zhangsan', age: 18};
let obj2 = obj;
赋值前
赋值后
当我们修改数据之后obj和obj2的值都会改变
obj.name = 'lisi';
引用数据深拷贝需要将数据源进行一个拷贝
let obj = {name: 'zhangsan', age: 18};
let obj2 = {};
obj2.name = obj.name;
obj2.age = obj.age;
按照这种思路实现一个深拷贝方法
function cloneDeep (data) {
/*
判断数据类型
只处理需要深拷贝的类型 (Array, Object, Set, Map, Date);
*/
switch (data.constructor) {
case Array:
return data.reduce((p, c) => {
return [...p, c];
}, []);
case Object:
return Object.keys(data).reduce((p, c) => {
return {
...p,
[c]: data[c]
}
}, {});
case Set:
let set = new Set();
data.forEach(item => {
set.add(item);
});
return set;
case Map:
let m = new Map();
return Object.keys(data).forEach(item => {
m.set(item, data[item])
});
return m;
case Date:
return new data.constructor(data);
return;
}
}