前端全面的深拷贝(考虑map,set,symbol, function)

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);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值