// const cloneTags = {
// DateTag
// }
const MapTag = '[object Map]';
const SetTag = '[object Set]';
const DateTag = '[object Date]';
const RegExpTag = '[object RegExp]';
const FunctionTag = '[object Function]';
function clone(value, map = new Map()) {
// 直接拷贝原始类型数据
if (!clone.__isObject(value)) return value;
const isArr = Array.isArray(value);
const tag = clone.__objToStr(value);
let cloneTarget = new value.constructor();
if (map.get(value)) {
return map.get(value);
}
map.set(value, cloneTarget);
// 拷贝 Map
if (tag === MapTag) {
value.forEach((v, k) => {
cloneTarget.set(k, clone(v, map));
});
return cloneTarget;
}
// 拷贝 Set
if (tag === SetTag) {
value.forEach(v => {
cloneTarget.add(clone(v, map));
});
return cloneTarget;
}
// 拷贝 Function
if (tag === FunctionTag) {
const bodyReg = /(?<=\{)(.|\n)+(?=\})/m;
const paramReg = /(?<=\()(.)+(?=\)\s*{)/;
const funcStr = value.toString();
// 箭头函数无prototype, 判断是否为箭头函数
if (value.prototype) {
const body = bodyReg.exec(funcStr);
const param = paramReg.exec(funcStr);
if (body) {
if (param) {
const params = param[0].split(',');
return new Function(...params, body[0]);
} else {
return new Function(body[0]);
}
} else {
return null;
}
} else {
// 箭头函数通过 eval 生成
return eval(funcStr);
}
}
// 拷贝 Date
if (tag === DateTag) {
return new value.constructor(value);
}
// 拷贝数组和对象
for (const key in value) {
cloneTarget[key] = clone(value[key], map);
}
return cloneTarget;
}
function __objToStr(o) {
return Object.prototype.toString.call(o);
}
clone.__objToStr = __objToStr;
function __isObject(o) {
return o !== null && (typeof o === 'object' || typeof o === 'function');
}
clone.__isObject = __isObject;
const myobj = {
a: { b: { e: 1 }, c: [1,2,3,4], d: 3 },
func: function(a,b,c){console.log(123); return {a:1}},
func0: (a)=>console.log(a),
date: new Date(191991)
};
myobj.my = myobj;
const newobj = clone(myobj)
console.log(newobj.date === myobj.date);
console