16. js copy (shallow copy, deep copy)
Native method:
How to implement a shallow copy
1. Use Object.assign():
let shallowCopy = Object.assign({
},originalObject);
2. Use the Spread operator:
let shallowCopy = {
...originalObject };
3. Use the for...in loop:
let shallowCopy = {
};
for (let key in originalObject) {
shallowCopy[key] = originalObject[key];
}
How to implement deep copy
Using JSON.parse() and JSON.stringify()
let deepCopy = JSON.parse(JSON.stringify(originalObject));
- function exists in the source object
- There is a circular reference in the source object
- There are Map and Set data types in the source object
The occurrence of the above situation will lead to serious consequences, and the above method will be automatically ignored
Handwritten deep copy function
function deepClone(obj) {
// 如果该对象不是对象(即为基本数据类型),则直接返回该值
if (typeof obj != "object") {
return obj;
}
// 如果该对象是数组,则创建一个空数组;否则创建一个空对象
let res = Array.isArray(obj) ? [] : {
};
// 遍历该对象的属性
for (let key in obj) {
// 如果该属性是该对象的自身属性(即不是继承自原型链的属性)
if (obj.hasOwnProperty(key)) {
// 将该属性的值复制一份
res[key] = deepClone(obj[key]);
}
}
// 返回复制的对象
return res;
}
//测试
let obj = {
a: 1,
b: [1, 2, 3],
c: {
d: 1
}
}
obj.self = obj;
console.log(copyObj);
The above method encounters cyclic access and will recurse infinitely
function deepClone(obj) {
// 创建一个 Map 对象,用来存储已经复制的对象
let map = new Map();
// 定义 doClone 函数,用于递归复制对象
function doClone(obj) {
// 如果该对象不是对象(即为基本数据类型),则直接返回该值
if (typeof obj != "object") {
return obj;
}
// 如果该对象已经被复制过,则直接返回复制的对象
if (map.has(obj)) return map.get(obj);
// 如果该对象是数组,则创建一个空数组;否则创建一个空对象
let res = Array.isArray(obj) ? [] : {
};
//将创建的对象放入Map中
map.set(obj, res);
// 遍历该对象的属性
for (let key in obj) {
// 如果该属性是该对象的自身属性(即不是继承自原型链的属性)
if (obj.hasOwnProperty(key)) {
// 将该属性的值复制一份
res[key] = doClone(obj[key]);
}
}
// 返回复制的对象
return res;
}
// 返回递归调用 doClone 函数的结果,即深拷贝后的对象
return doClone(obj);
}