深拷贝
手写深拷贝函数:满足了基本类型的拷贝,函数,set,map,symbol等的拷贝。
// 深拷贝 基本类型变量 symbol,方法 都可以拷贝
function isObject(val) {
const valType = typeof val;
return val && (valType === "object" || valType === "function");
}
function deepCopy(originValue) {
// 创建一个map 主要是为了解决循环引用
const loopRef = new WeakMap();
function _deepCopy(originValue) {
// symbol作为值的时候 我们需要重新创建一个symbol对象
if (typeof originValue === "symbol") {
return Symbol(originValue.description);
}
// 基本类型,以及函数类型 直接返回 函数是为了复用 不需要重新创建一个
if (!isObject(originValue) || typeof originValue === "function") return originValue;
// 是set 和 map
if (Object.prototype.toString.call(originValue).slice(8, -1) === "Set") {
const newSet = new Set();
originValue.forEach(value => {
newSet.add(_deepCopy(value));
});
return newSet;
}
if (originValue instanceof Map) {
const newMap = new Map();
originValue.forEach((value, key) => {
newMap.set(key, _deepCopy(value));
});
return newMap;
}
// 如果当前的对象已经在loopRef循环引用map里面存在了,不需要再次创建新对象 直接取出来返回即可了
if (loopRef.has(originValue)) return loopRef.get(originValue);
// 是对象 数组
const newObject = Array.isArray(originValue) ? [] : {};
// 把对象添加到我们的循环引用map中
loopRef.set(originValue, newObject);
for (const key in originValue) { // symbol作为key的时候 不会遍历到
newObject[key] = _deepCopy(originValue[key]);
}
// 拿到作为key的symbol
const symbolKeys = Object.getOwnPropertySymbols(originValue);
for (const key of symbolKeys) {
newObject[key] = _deepCopy(key);
}
return newObject;
}
return _deepCopy(originValue);
}