Skip to content

clone

深度克隆一个对象或数组。

基础用法

typescript
import { clone } from 'radash'

const original = {
  name: 'Alice',
  age: 25,
  hobbies: ['reading', 'swimming'],
  address: {
    city: 'Beijing',
    country: 'China'
  }
}

const cloned = clone(original)
// 现在 cloned 是 original 的深度副本
// 修改 cloned 不会影响 original

语法

typescript
function clone<T>(value: T): T

参数

  • value (T): 要克隆的值,可以是任何类型

返回值

返回一个深度克隆的值,与原值完全独立。

示例

克隆简单对象

typescript
import { clone } from 'radash'

const original = { name: 'Alice', age: 25 }
const cloned = clone(original)

cloned.age = 30
console.log(original.age) // 25 (原对象未改变)
console.log(cloned.age)   // 30

克隆嵌套对象

typescript
import { clone } from 'radash'

const original = {
  user: {
    name: 'Bob',
    preferences: {
      theme: 'dark',
      language: 'en'
    }
  },
  settings: {
    notifications: true
  }
}

const cloned = clone(original)

cloned.user.preferences.theme = 'light'
console.log(original.user.preferences.theme) // 'dark' (原对象未改变)
console.log(cloned.user.preferences.theme)   // 'light'

克隆数组

typescript
import { clone } from 'radash'

const original = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  [1, 2, 3]
]

const cloned = clone(original)

cloned[0].name = 'Charlie'
cloned[2][0] = 999

console.log(original[0].name) // 'Alice' (原数组未改变)
console.log(original[2][0])   // 1 (原数组未改变)
console.log(cloned[0].name)   // 'Charlie'
console.log(cloned[2][0])     // 999

克隆基本类型

typescript
import { clone } from 'radash'

// 数字
const num = 42
const clonedNum = clone(num)
console.log(clonedNum) // 42

// 字符串
const str = 'hello'
const clonedStr = clone(str)
console.log(clonedStr) // 'hello'

// 布尔值
const bool = true
const clonedBool = clone(bool)
console.log(clonedBool) // true

// null
const nullValue = null
const clonedNull = clone(nullValue)
console.log(clonedNull) // null

克隆日期对象

typescript
import { clone } from 'radash'

const original = new Date('2023-01-01')
const cloned = clone(original)

cloned.setFullYear(2024)

console.log(original.getFullYear()) // 2023 (原日期未改变)
console.log(cloned.getFullYear())   // 2024

克隆正则表达式

typescript
import { clone } from 'radash'

const original = /hello/g
const cloned = clone(original)

console.log(original.source) // 'hello'
console.log(cloned.source)   // 'hello'
console.log(original.flags)  // 'g'
console.log(cloned.flags)    // 'g'

克隆函数

typescript
import { clone } from 'radash'

const original = (x: number) => x * 2
const cloned = clone(original)

console.log(original(5)) // 10
console.log(cloned(5))   // 10

克隆Map和Set

typescript
import { clone } from 'radash'

// Map
const originalMap = new Map([
  ['key1', 'value1'],
  ['key2', { nested: 'value2' }]
])
const clonedMap = clone(originalMap)

clonedMap.get('key2').nested = 'new value'

console.log(originalMap.get('key2').nested) // 'value2' (原Map未改变)
console.log(clonedMap.get('key2').nested)   // 'new value'

// Set
const originalSet = new Set([1, 2, { value: 3 }])
const clonedSet = clone(originalSet)

for (const item of clonedSet) {
  if (typeof item === 'object') {
    item.value = 999
  }
}

console.log([...originalSet]) // [1, 2, { value: 3 }] (原Set未改变)
console.log([...clonedSet])   // [1, 2, { value: 999 }]

处理循环引用

typescript
import { clone } from 'radash'

const original: any = { name: 'Alice' }
original.self = original // 循环引用

const cloned = clone(original)

console.log(cloned.name)        // 'Alice'
console.log(cloned.self === cloned) // true (循环引用被保持)

注意事项

  1. 深度克隆: clone 会递归地克隆所有嵌套的对象和数组
  2. 保持引用: 循环引用会被正确处理
  3. 性能: 对于大型对象,克隆操作可能比较耗时
  4. 函数克隆: 函数会被直接复制,而不是重新创建
  5. 原型链: 原型链信息会被保持

与其他方法的区别

  • Object.assign(): 只进行浅拷贝
  • {...obj}: 只进行浅拷贝
  • JSON.parse(JSON.stringify()): 无法处理函数、undefined、循环引用等
  • clone(): 进行深度克隆,处理所有类型

实际应用场景

  1. 状态管理: 克隆状态对象以避免直接修改
  2. 数据备份: 创建数据的备份副本
  3. 测试: 在测试中创建独立的测试数据
  4. 缓存: 克隆缓存数据以避免污染
  5. 配置: 克隆配置对象以进行本地修改

Released under the MIT License.