deepClone
深克隆
参数
参数名 | 参数类型 | 参数说明 |
---|---|---|
target | any | 要克隆的对象 |
map | WeakMap<object, any> | 用来存对象做循环引用的判断 |
源代码&使用
ts
import { deepClone } from '@manzhixing/utilsxy';
const map = new Map();
map.set("name", "chengbotao");
const set = new Set();
set.add("utilsxy");
set.add("chengbotao");
const obj = {
field: 1,
fieldUn: undefined,
fieldObj: {
age: 28,
},
fieldArr: [2, 4, 8],
empty: null,
map,
set,
bool: new Boolean(true),
num: new Number(2),
str: new String(2),
symbol: Object(Symbol(1)),
date: new Date(),
reg: /\d+/,
error: new Error(),
fun: () => {
console.log("Hello Family!");
},
fun1: function (a, b) {
return a + b;
},
};
const copy = deepClone(obj);
ts
/*
* @Author: Chengbotao
* @Contact: https://github.com/chengbotao
*/
export function deepClone(target: any, map = new WeakMap()) {
if (target === null || typeof target !== 'object') {
return target;
}
if (map.get(target)) {
return target;
}
const Ctor = target.constructor;
const ctorName = Ctor.name;
if (/^(RegExp|Date|Number|String|Boolean|Error)$/i.test(ctorName)) {
return new Ctor(target);
}
if (ctorName === 'Symbol') {
return Object(Object.prototype.valueOf.call(target));
}
if (ctorName === 'Map') {
const cloneMap = new Map();
map.set(target, true);
target.forEach((value: unknown, key: unknown) => {
cloneMap.set(deepClone(key, map), deepClone(value, map));
});
return cloneMap;
}
if (ctorName === 'Set') {
const cloneSet = new Set();
map.set(target, true);
target.forEach((value: unknown) => {
cloneSet.add(deepClone(value, map));
});
return cloneSet;
}
map.set(target, true);
const cloneResult: Record<string, any> = Array.isArray(target) ? [] : {};
Object.getOwnPropertyNames(target).forEach((key: string) => {
cloneResult[key] = deepClone(target[key], map);
});
return cloneResult;
}