function isObject(obj) {
return obj !== null && (typeof obj === "function" || typeof obj === "object");
}
function deepClone(value, map = new WeakMap()) {
// 当value为set时,返回一个新set
if (value instanceof Set) return new Set([...value]);
// 当value为map时,返回一个新map
if (value instanceof Map) return new Map([...value]);
// 当value为symbol时,返回一个新symbol
if (typeof value === "symbol") return Symbol(value.description);
// 当value为function时,直接返回原function
if (typeof value === "function") return value;
// 当value不为对象时,直接返回value
if (!isObject(value)) return value;
// 当map中存在value时,直接返回map中的value
if (map.has(value)) {
return map.get(value);
}
// 判断value值是否为数组,为数组时创建空数组
const newObj = Array.isArray(value) ? [] : {};
// 将函数接收到的value和新创建的obj保存到map中
map.set(value, newObj);
for (let key in value) {
// 递归处理value值
newObj[key] = deepClone(value[key], map);
}
// 获取symbol为key的所有数据
const symbols = Object.getOwnPropertySymbols(value);
for (let sym of symbols) {
newObj[sym] = deepClone(value[sym], map);
}
return newObj;
}
const symbolKey = Symbol("symbolKey");
const symbolValue = Symbol("symbolValue");
const set = new Set([1, 2, 3, 4, 5]);
const map = new Map([
["name", "alice"],
["age", 20],
]);
const obj = {
name: "alice",
friend: {
name: "windy",
address: {
city: "Beijing",
},
},
hobbies: ["swiming", "dancing", "tennis"],
styding() {
return "I am reading~";
},
[symbolKey]: "key",
value: symbolValue,
set,
map,
};
obj.info = obj;
const user = deepClone(obj);
console.log("原对象obj-", obj);
console.log("新对象user-", user);