可设计支持 deep 参数的拷贝函数:deep 为 true 时优先用 structuredclone(现代环境),否则降级浅拷贝;基础版处理对象/数组,兼容版递归实现并扩展 date/regexp/map/set 等类型,函数、symbol 等默认不拷贝。

可以设计一个接受 deep 参数的拷贝函数,内部根据该参数决定调用浅拷贝逻辑(如展开运算符、Object.assign)还是深拷贝逻辑(如递归、structuredClone 或 JSON 方案)。关键在于统一输入输出接口,并合理处理边界情况(如 null、undefined、非对象类型、循环引用等)。
基础版:支持对象/数组,用 structuredClone + 浅拷贝回退
现代浏览器和 Node.js 17+ 支持 structuredClone,它能安全处理多数可克隆值(不包括函数、undefined、Symbol、Date、RegExp 等),且自动规避循环引用。对不支持的环境或特殊类型,可降级为浅拷贝:
- 若传入
deep: true且structuredClone可用,直接使用它 - 若
deep: false,用扩展运算符(数组)或{...obj}(普通对象) - 若
deep: true但structuredClone不可用,抛错或返回浅拷贝并警告
兼容版:手动实现简易深拷贝(无循环检测)
当需支持老环境或要控制行为时,可写一个轻量递归函数,只处理 plain object 和 array,其他类型(Date、RegExp、Map、Set 等)按需扩展:
- 先判断是否为 null 或原始类型(string/number/boolean/symbol/bigint),直接返回原值
- 用
Array.isArray()区分数组,用Object.prototype.toString.call(x) === '[object Object]'判断 plain object - 递归遍历键值,对每个属性值按同样逻辑拷贝
- 浅拷贝分支跳过递归,仅做一层展开或
Object.assign({}, obj)
增强健壮性:处理常见特殊类型
真实项目中常遇到 Date、RegExp、Map、Set 等。可在深拷贝分支中添加特例处理:
-
instanceof Date→new Date(date.getTime()) -
instanceof RegExp→new RegExp(regexp.source, regexp.flags) -
instanceof Map→new Map([...map]) -
instanceof Set→new Set(set) - 注意:函数、undefined、Symbol 默认不拷贝(保持原引用或忽略),避免意外行为
使用示例与注意事项
函数签名建议为 clone(value, { deep = false } = {}),这样调用清晰:
-
clone({ a: 1, b: { c: 2 } }, { deep: false })→ 浅拷贝,b仍共享引用 -
clone([1, { x: 2 }], { deep: true })→ 深拷贝,嵌套对象也被复制 - 避免对含函数、DOM 节点、window 等不可序列化对象强行深拷贝
- 如需完整循环引用支持,应引入专业库(如
lodash.cloneDeep)或自行实现 WeakMap 缓存机制
不复杂但容易忽略细节。核心是明确需求范围:是否需要兼容旧环境?是否必须支持所有内置类型?根据实际场景选方案,不必追求“全能”。











