JavaScript深拷贝

2020-04-13  本文已影响0人  六寸光阴丶

写在前面

如果本文对您有所帮助,就请点个关注吧!

手写JavaScript深拷贝

源代码

function deepCopy(obj, cache = []) {
  // 拷贝函数
  if (typeof obj === 'function') {
    return eval(`(${obj.toString()})`)
  }
  // 拷贝基本数据类型
  if (obj === null || typeof obj !== 'object') {
    return obj
  }
  // 拷贝日期
  if (Object.prototype.toString.call(obj) === '[object Date]') return new Date(obj)
  // 拷贝正则
  if (Object.prototype.toString.call(obj) === '[object RegExp]') return new RegExp(obj)
  // 拷贝错误
  if (Object.prototype.toString.call(obj) === '[object Error]') return new Error(obj)
  // 处理循环引用
  const item = cache.filter(item => item.original === obj)[0]
  if (item) return item.copy
  // 对象数组分类讨论
  let copy = Array.isArray(obj) ? [] : {}
  cache.push({
    original: obj,
    copy
  })
  // 循环递归拷贝
  Object.keys(obj).forEach(key => {
    copy[key] = deepCopy(obj[key], cache)
  })
  return copy
}

测试

let obj = {
  num: 0,
  str: 'str',
  boolean: true,
  unf: undefined,
  nul: null,
  symbol: Symbol(),
  obj: {
    name: '我是一个对象',
    id: 1
  },
  arr: [0, 1, 2],
  func: function () {
    console.log('我是一个函数')
  },
  func2: () => {
    console.log('我是一个函数')
  },
  date: new Date(),
  reg: new RegExp('/我是一个正则/ig'),
  err: new Error('我是一个错误')
}

obj.obj.d = obj
console.log(obj)
let clone = deepCopy(obj)
console.log(clone)

测试结果

{ num: 0,
  str: 'str',
  boolean: true,
  unf: undefined,
  nul: null,
  symbol: Symbol(),
  obj: { name: '我是一个对象', id: 1, d: [Circular] },
  arr: [ 0, 1, 2 ],
  func: [Function: func],
  func2: [Function: func2],
  date: 2020-04-14T04:37:28.637Z,
  reg: /\/我是一个正则\/ig/,
  err:
   Error: 我是一个错误
       at Object.<anonymous> (d:\Document\Programming\Python\clone.js:21:8)
       at Module._compile (internal/modules/cjs/loader.js:778:30)
       at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
       at Module.load (internal/modules/cjs/loader.js:653:32)
       at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
       at Function.Module._load (internal/modules/cjs/loader.js:585:3)
       at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
       at startup (internal/bootstrap/node.js:283:19)
       at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3) }
{ num: 0,
  str: 'str',
  boolean: true,
  unf: undefined,
  nul: null,
  symbol: Symbol(),
  obj: { name: '我是一个对象', id: 1, d: [Circular] },
  arr: [ 0, 1, 2 ],
  func: [Function],
  func2: [Function],
  date: 2020-04-14T04:37:28.637Z,
  reg: /\/我是一个正则\/ig/,
  err:
   Error: Error: 我是一个错误
       at deepCopy (d:\Document\Programming\Python\clone.js:39:72)
       at Object.keys.forEach.key (d:\Document\Programming\Python\clone.js:48:17)
       at Array.forEach (<anonymous>)
       at deepCopy (d:\Document\Programming\Python\clone.js:47:20)
       at Object.<anonymous> (d:\Document\Programming\Python\clone.js:53:14)
       at Module._compile (internal/modules/cjs/loader.js:778:30)
       at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
       at Module.load (internal/modules/cjs/loader.js:653:32)
       at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
       at Function.Module._load (internal/modules/cjs/loader.js:585:3) }
上一篇下一篇

猜你喜欢

热点阅读