deepClone
深度克隆对象或数组,处理循环引用和各种数据类型。
函数签名
typescript
// 完整版深拷贝
function deepClone<T>(value: T, options?: DeepCloneOptions): T
interface DeepCloneOptions {
includeNonEnumerable?: boolean
includeSymbol?: boolean
includePrototype?: boolean
customClone?: (value: any, defaultClone: (v: any) => any) => any
}
// JSON 方式深拷贝
function deepCloneJSON<T>(value: T): T
// structuredClone 方式
function deepCloneStructured<T>(value: T, deps: DeepCloneStructuredDeps): T
interface DeepCloneStructuredDeps {
structuredClone?: <T>(value: T) => T
}参数
deepClone
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
value | T | 是 | - | 要克隆的值 |
options | DeepCloneOptions | 否 | {} | 克隆选项 |
options.includeNonEnumerable | boolean | 否 | false | 是否克隆不可枚举属性 |
options.includeSymbol | boolean | 否 | false | 是否克隆 Symbol 属性 |
options.includePrototype | boolean | 否 | false | 是否保持原型链 |
options.customClone | Function | 否 | - | 自定义克隆函数 |
deepCloneJSON
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
value | T | 是 | 要克隆的值 |
deepCloneStructured
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
value | T | 是 | 要克隆的值 |
deps | DeepCloneStructuredDeps | 是 | 依赖注入对象,包含 structuredClone 函数 |
前置依赖
deepCloneStructured
| 参数名 | 类型 | 说明 |
|---|---|---|
deps.structuredClone | <T>(value: T) => T | structuredClone 函数(较新的浏览器原生 API) |
环境要求
- structuredClone: 原生深拷贝 API(Node.js 17+, 现代浏览器)
- 如果环境不支持,会自动 fallback 到
deepClone
typescript
const deps = {
structuredClone: typeof structuredClone !== 'undefined' ? structuredClone : undefined
}返回值
| 类型 | 说明 |
|---|---|
T | 克隆后的值 |
工作原理
deepClone (完整版)
- 处理基本类型:直接返回
- 检查循环引用:使用 WeakMap 记录已克隆对象
- 调用自定义克隆函数(如果提供)
- 处理特殊对象类型:
- Date: 创建新 Date 实例
- RegExp: 复制 source 和 flags
- Error: 复制 message、stack、name
- Map/Set: 递归克隆键和值
- WeakMap/WeakSet: 创建新实例
- ArrayBuffer: 复制二进制数据
- TypedArray/DataView: 创建新实例并复制数据
- 处理数组:递归克隆每个元素
- 处理普通对象:
- 根据选项决定是否保持原型链
- 递归克隆可枚举属性
- 根据选项决定是否克隆不可枚举属性和 Symbol 属性
deepCloneJSON (简易版)
- 使用
JSON.stringify将对象序列化为字符串 - 使用
JSON.parse将字符串反序列化为新对象 - 缺点:无法处理函数、undefined、Symbol、循环引用、Date、RegExp 等
- 注意:
JSON是 JavaScript 标准内置对象,所有环境均可用
deepCloneStructured (原生 API)
- 如果提供了
deps.structuredClone:使用原生 API - 否则:Fallback 到
deepClone - 优点:性能最好,支持更多类型(Blob、File)
- 缺点:不支持函数和 Symbol
- 需要依赖注入:因为是较新的 API,旧环境不支持
适用于需要完全隔离原对象和克隆对象的场景。