JavaScript 实现深拷贝

JavaScript 的 deepClone(深拷贝)需要处理 基本类型、引用类型(对象、数组)、特殊对象(日期、正则、函数) 等场景,还要避免 循环引用 导致的死循环

  1. 支持基本类型 :数字、字符串、布尔值、nullundefinedSymbolBigInt(直接返回原值,无拷贝成本)。
  2. 支持引用类型
    • 普通对象({})、数组([]
    • 特殊对象:Date(拷贝时间戳)、RegExp(拷贝源正则和修饰符)
  3. 解决循环引用 :用 WeakMap 缓存已拷贝的对象,避免循环引用导致的栈溢出(例如 a.b = a 场景)。
  4. 保留属性特性 :通过 Reflect.ownKeys 遍历所有可枚举 / 不可枚举属性,包括 Symbol 类型的键(比 for...in 更全面)。
JavaScript 复制代码
function deepClone(target, hash = new WeakMap()) {
  // 1. 处理基本类型和 null/undefined(直接返回,无需拷贝)
  if (target === null || typeof target !== "object") return target
  // 2. 处理循环引用(已拷贝过的对象直接返回缓存)
  if (hash.has(target)) return hash.get(target)

  let cloneObj

  // 3. 处理日期对象
  if (target instanceof Date) {
    cloneObj = new Date(target)
    hash.set(target, cloneObj)
    return cloneObj
  }

  // 4. 处理正则对象
  if (target instanceof RegExp) {
    cloneObj = new RegExp(target.source, target.flags)
    hash.set(target, cloneObj)
    return cloneObj
  }

  // 5. 处理 Map
  if (target instanceof Map) {
    cloneObj = new Map()
    hash.set(target, cloneObj)
    target.forEach((value, key) => {
      cloneObj.set(deepClone(key, hash), deepClone(value, hash))
    })
    return cloneObj
  }

  // 6. 处理 Set
  if (target instanceof Set) {
    cloneObj = new Set()
    hash.set(target, cloneObj)
    target.forEach((value) => {
      cloneObj.add(deepClone(value, hash))
    })
    return cloneObj
  }

  // 7. 处理数组和普通对象(区分数组和对象的构造器)
  cloneObj = Array.isArray(target) ? [] : {}
  hash.set(target, cloneObj)

  // 8. 遍历对象/数组的可枚举属性(包括 Symbol 类型)
  Reflect.ownKeys(target).forEach((key) => {
    // 递归拷贝属性值,同时传递 hash 缓存
    cloneObj[key] = deepClone(target[key], hash)
  })

  return cloneObj
}
相关推荐
@大迁世界7 小时前
43.HTML 事件处理和 React 事件处理有什么区别?
前端·javascript·react.js·html·ecmascript
CloneCello7 小时前
AI时代程序员认知调整指南
前端
ZC跨境爬虫8 小时前
跟着 MDN 学 HTML day_38:(DocumentFragment 文档片段接口详解)
前端·javascript·ui·html·音视频
@大迁世界9 小时前
41.ShadCN 是什么?它如何和 Tailwind CSS 集成,从而更容易构建可访问且可自定义的 React 组件?
前端·javascript·css·react.js·前端框架
千叶风行9 小时前
Text-to-SQL 技术设计与注意事项
前端·人工智能·后端
软件开发技术深度爱好者9 小时前
HTML5+JavaScript读取DOCX 文档完整内容
前端·html5
幽络源小助理10 小时前
苹果CMS V10 MXPro V4.5模版下载, 自适应视频主题源码, 幽络源源码
前端·开源·源码·php源码
kyriewen10 小时前
坏了,黑客学会用AI写外挂了
前端·程序员·ai编程
xiangxiongfly91511 小时前
Vue3 根据角色权限动态加载路由
前端·javascript·vue.js·动态加载路由
达达尼昂11 小时前
Claude 多 Agent 系统:从零搭建一个 4 Agent 团队
前端·架构·ai编程