深拷贝实现

/** 深拷贝实现
 * 1. 基本功能实现,解决嵌套对象问题
 * 2. 对数组类型的处理
 * 3. 对函数类型的处理
 * 4. 对 Symbol类型的处理(分别作为键值时的处理)
 * 5. 对 Set 类型的处理
 * 6. 对 Map 类型的处理
 * 7. 解决循环引用问题
 */
// *判断是否为对象
function isObject(value) {
  const valueType = typeof value
  return value !== null && (valueType === 'object' || valueType == 'function')
}

function deepClone(originValue, map = new WeakMap()) {

  //TODO 判断 originValue 是否为 Set 类型
  if (originValue instanceof Set) {
    return new Set([...originValue])
  }

  //TODO 判断 originValue 是否为 Map 类型
  if (originValue instanceof Map) {
    return new Map([...originValue])
  }

  //TODO 判断 originVlaue 是否为 symbol 类型
  if (typeof originValue === 'symbol') {
    return Symbol(originValue.description)
  }

  //TODO 判断 originValue 是否为函数类型
  if (typeof originValue === 'function') {
    return originValue
  }

  //TODO 判断 originValue 是否为对象类型
  if (!isObject(originValue)) {
    return originValue
  }

  // 2. 判断 newObj 是否已存在
  if (map.has(originValue)) {
    return map.get(originValue)
  }

  //TODO 判断 originValue 是否为数组类型
  const newObj = Array.isArray(originValue) ? [] : {}

  // 1. 将 newObj保存下来,用于下次运行时判断是否已经创建了 newObj
  map.set(originValue, newObj)

  for (const key in originValue) {
    newObj[key] = deepClone(originValue[key], map)
  }

  //TODO 对 symbol类型的 key做特殊处理
  const symbolKeys = Object.getOwnPropertySymbols(originValue)
  for (const skey of symbolKeys) {
    newObj[skey] = deepClone(originValue[skey], map)
  }

  return newObj
}

// 测试代码

let s1 = Symbol('aaa')
let s2 = Symbol('bbb')

const obj = {
  name: 'CoderBin',
  friend: {
    name: 'Jack'
  },
  b: undefined,
  s2: s2,
  // 待优化
  skill: ['js', 'vue', 'react'],
  foo: () => { },
  [s1]: 's11',
  set: new Set(['a', 'b', 'c']),
  map: new Map([
    ['a', 'aa'],
    ['b', 'bb']
  ])
}

obj.info = obj

const newObj = deepClone(obj)

console.log(newObj)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值