1. Using third-party libraries
Use method (see lodash Chinese official website for detailslodash
)cloneDeep()
import lodash from 'lodash';
let obj = {
a: {
b: '阿潔'
},
c: '深拷贝'
}
const newObj = lodash.cloneDeep(obj)
2. Simple deep copy
In addition to the basic data type ( null、string、boolean、undefined、number、symbol
), if there are no time type and regular expression objects in the reference data type, simple JSON serialization can be used for conversion.
let cloneObj = JSON.parse(JSON.stringify(obj))
Note: This deep copy is not recommended if the object content item is undefined, null, Date, RegExp, function... may cause problems
3. Recursive version
1. Considering the existence of a deep copy of Date and regular expressions (considering the most complete and relatively complicated deep copy)
export function cloneDeep(data) {
//string,number,bool,null,undefined,symbol
//object,array,date
if (data && typeof data === "object") {
//针对函数的拷贝
if (typeof data === "function") {
let tempFunc = data.bind(null);
tempFunc.prototype = cloneDeep(data.prototype);
return tempFunc;
}
// 根据不同的数据类型的深拷贝
switch (Object.prototype.toString.call(data)) {
case "[object String]":
return data.toString();
case "[object Number]":
return Number(data.toString());
case "[object Boolean]":
return new Boolean(data.toString());
case "[object Date]":
return new Date(data.getTime());
case "[object Array]":
var arr = [];
for (let i = 0; i < data.length; i++) {
arr[i] = cloneDeep(data[i]);
}
return arr;
//js自带对象或用户自定义类实例
case "[object Object]":
var obj = {
};
for (let key in data) {
//会遍历原型链上的属性方法,可以用hasOwnProperty来控制 (obj.hasOwnProperty(prop)
obj[key] = cloneDeep(data[key]);
}
return obj;
}
} else {
//string,number,bool,null,undefined,symbol
return data;
}
}
2. Does not consider the deep copy of Date and regular expressions (the simplified version above is also a commonly used one)
function cloneDeep (target) {
// 判断是否是对象
if (typeof target === 'object') {
// 兼容数组与对象
let obj = Array.isArray(target) ? [] : {
}
for (let key in target) {
obj[key] = cloneDeep(target[key])
}
return obj
} else {
return target
}
}