美文网首页让前端飞Web前端之路
js 如何实现深拷贝deepClone

js 如何实现深拷贝deepClone

作者: 前端收藏家 | 来源:发表于2020-06-07 07:29 被阅读0次

如果不考虑RegExp, Function, Symbol, 循环引用的问题,那么使用JSON是一个不错的选择。

比如有这样一个对象:

var target = {
  name: 'fedaily',
  age: 1,
  topics: ['react', 'vue', 'css']
}

var copyTarget = JSON.parse(JSON.stringify(target))
console.log(copyTarget) // { name: 'fedaily', age: 1, topics: ['react', 'vue', 'css'] }

copyTarget.topics.push('webpack')

// target不变
console.log(target) // { name: 'fedaily', age: 1, topics: ['react', 'vue', 'css'] }

但是如果需要考虑各种引用类型,以及循环引用等问题,那么还是需要手动实现这些拷贝逻辑,这里参照lodash深拷贝的实现逻辑,但是精简了很多,我们来看看如何做:

const regexpTag = '[object RegExp]'

function deepClone(value, stack = new WeakMap()) {
  if (!isObject(value)) {
    return value
  }

  let result = Array.isArray(value) ? [] : {}

  // 函数直接返回
  if (typeof value === 'function') {
    return value
  }

  // 处理引用类型的拷贝
  result = initCloneByTag(value, getTag(value))

  // 处理循环引用
  if (stack.has(value)) {
    return stack.get(value)
  }
  stack.set(value, result)

  // 这里没有处理key是Symbol的情况
  // for in 不会枚举Symbol的key
  // 可以通过Object.getOwnPropertySymbols获取所有Symbol的key
  for (let key in value) {
    result[key] = deepClone(value[key], stack)
  }
  return result
}

function isObject (value) {
  const type = typeof value
  return value != null && (type === 'object' || type === 'function')
}

function getTag(value) {
  if (value == null) {
    return value === undefined ? '[object Undefined]' : '[object Null]'
  }
  return Object.prototype.toString.call(value)
}

function cloneRegExp(regexp) {
  const result = new regexp.constructor(regexp.source, /\w*$/.exec(regexp))
  result.lastIndex = regexp.lastIndex
  return result
}

function initCloneByTag(object, tag) {
  const Ctor = object.constructor
  // 可以在这里处理
  // arrayBuffer, int32array, dataview等情况
  switch (tag) {
    case regexpTag:
      return cloneRegExp(object)

    default:
      return {}
  }
}

相关文章

  • js 如何实现深拷贝deepClone

    如果不考虑RegExp, Function, Symbol, 循环引用的问题,那么使用JSON是一个不错的选择。 ...

  • 受虐之路(2)

    1.深拷贝与浅拷贝深拷贝只针对复杂数据类型如何实现深拷贝?1)递归function deepClone(obj){...

  • JS深拷贝

    深拷贝,拷贝引用对象的引用对地址和栈。先编辑deepClone.js文件 在html中引入deepClone.js...

  • 深拷贝 浅拷贝

    一、对象深拷贝实现 1. 使用递归的方式实现深拷贝 function deepClone(obj){ let ob...

  • vue-深拷贝,深克隆,deepclone最佳方案

    vue--深拷贝,深克隆,deepclone最佳方案

  • 多类型深拷贝

    // 深拷贝:对对象内部进行深拷贝,支持 Array、Date、RegExp、DOMconst deepClone...

  • js浅拷贝深拷贝

    js浅拷贝,深拷贝的简单实现 基础数据 浅拷贝 深拷贝

  • iOS基础知识点(网络摘抄)

    1.父类实现深拷贝时,子类如何实现深拷贝。父类没有实现深拷贝时,子类如何实现深拷贝? 深拷贝同浅拷贝的区别:...

  • iOS面试基础一

    #父类实现深拷贝时,子类如何实现深度拷贝.父类没有实现深拷贝时,子类如何实现深度拷贝.# <(1)深拷贝同浅拷贝的...

  • 深拷贝、浅拷贝

    父类实现深拷贝时,子类如何实现深度拷贝。父类没有实现深拷贝时,子类如何实现深度拷贝。 深拷贝同浅拷贝的区别:浅拷贝...

网友评论

    本文标题:js 如何实现深拷贝deepClone

    本文链接:https://www.haomeiwen.com/subject/tcrrzhtx.html