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
}
相关推荐
weixin_471383034 分钟前
图片预解码缓存
前端·浏览器缓存·图片预解码
一起学开源9 分钟前
一文读懂 ReAct 范式:让 AI Agent 真正学会“思考+行动“
java·javascript·react.js·ecmascript·react·alibaba·智能体开发
郑洁文2 小时前
基于网络爬虫的Web敏感信息泄露自动化检测工具
前端·爬虫·网络安全·自动化
游九尘2 小时前
JavaScript 实现三段式版本号对比函数(app升级用)
javascript·uni-app
zhiSiBuYu05172 小时前
Claude-Code 新手极速上手指南
javascript·node.js
郑洁文2 小时前
可视化Web渗透分析工具的设计与实现
前端
罗超驿3 小时前
18.Web API 实战:元素与表单属性的获取和修改
开发语言·前端·javascript
边界条件╝3 小时前
微前端进阶(四)
前端·状态模式
无风听海3 小时前
JSON Web Token(JWT)完全指南
java·前端·json
山河已无恙3 小时前
BPF-eBPF 开发路线二:libbpf、CO-RE 与 libbpf-bootstrap认知
javascript·bootstrap·php