Skip to content

cloneDeep

创建对象或数组的深拷贝

1142 bytes
since v12.2.0

使用方法

深度克隆给定的对象或数组。默认情况下被克隆的嵌套对象只有:普通对象、非原生类实例、数组、Map 实例和 Set 实例。

默认行为旨在支持最常见的使用场景。如果您需要更多控制,请参见下面的”自定义克隆”。

默认情况下,非可枚举属性和计算属性会无损地复制。请注意,如果您需要更好的性能,可以选择退出此行为(请参见下面的”更快的克隆”)。

import * as _ from "radashi";
const obj = { a: 1, b: { c: 2 } };
const clone = _.cloneDeep(obj);
// => { a: 1, b: { c: 2 } }
console.log("clone !== obj", clone !== obj);
console.log("clone.b !== obj.b", clone.b !== obj.b);

更快的克隆

您可以传递 FastCloningStrategy 以获得更好的性能,但请记住以下权衡。

所有普通对象和类实例都使用 {...obj} 进行克隆。这意味着原始原型、计算属性和非可枚举属性不会被保留。

还要注意,像 RegExpDate 这样的内置复杂对象仍然不会使用此克隆策略进行克隆。如果您需要克隆这些对象类型,可以覆盖 cloneOther 函数。

自定义克隆

“克隆策略”控制 cloneDeep 如何处理某些对象类型。您可以传入自定义策略,甚至可以是部分策略。策略中任何未定义的方法都将继承默认逻辑。您的自定义方法可以返回 null 以使用默认逻辑,或者返回接收到的对象以跳过克隆。

import * as _ from "radashi";
_.cloneDeep(obj, {
// 如果数组未被冻结,则使用默认逻辑克隆数组。
cloneArray: (array) => (Object.isFrozen(array) ? array : null),
});

如果您在自定义方法中克隆对象,请确保在克隆嵌套对象之前将克隆传递给 track 函数。这里是一个使用 cloneOther 处理自定义类实例的示例。

import * as _ from "radashi";
_.cloneDeep(obj, {
cloneOther: (obj, track, clone) => {
if (obj instanceof MyClass) {
// 1. 创建新实例并跟踪它。
const clone = track(new MyClass());
// 2. 复制原始实例的属性。
for (const key in obj) {
clone[key] = clone(obj[key]);
}
// 3. 返回克隆的实例。
return clone;
}
// 对其他任何内容使用默认逻辑。
return null;
},
});