要深度克隆对象数组,必须使用能递归复制嵌套对象的方法;2. json.parse(json.stringify()) 虽常用,但会丢失函数、undefined、symbol、bigint,将日期转为字符串,正则变空对象,且不支持循环引用;3. lodash 的 _.clonedeep() 能处理日期、正则、map、set 等复杂类型,是更稳健的方案;4. 原生 structuredclone() api 支持日期、正则、数组、嵌套对象甚至循环引用,但不兼容老版本浏览器,是未来推荐的轻量选择;5. 自行实现递归克隆函数可行但复杂,需处理类型判断和循环引用,一般不建议。深度克隆的本质是切断引用关系,确保新旧对象完全独立,避免修改副本影响原始数据,这在状态管理等场景中至关重要。

在 JavaScript 里要深度克隆一个对象数组,可不是简单地用
...
slice()
说实话,在 JavaScript 里处理深度克隆,尤其是一个包含复杂对象的数组,最常见也最“偷懒”的方法就是
JSON.parse(JSON.stringify(originalArray))
undefined
Symbol
BigInt
如果你追求更稳健、更全面的解决方案,Lodash 库提供的
_.cloneDeep()
// 使用 Lodash 的 _.cloneDeep
import _ from 'lodash';
const originalArray = [
{ id: 1, name: 'Item A', details: { value: 10, tags: ['new', 'hot'] }, createdAt: new Date() },
{ id: 2, name: 'Item B', details: { value: 20, tags: ['old'] }, func: () => console.log('hi') }
];
const clonedArray = _.cloneDeep(originalArray);
// 验证深度克隆
clonedArray[0].details.value = 100;
clonedArray[1].name = 'Item C';
clonedArray[0].createdAt.setFullYear(2000); // 修改克隆后的日期
console.log('Original Item A Value:', originalArray[0].details.value); // 应该还是 10
console.log('Cloned Item A Value:', clonedArray[0].details.value); // 应该是 100
console.log('Original Item B Name:', originalArray[1].name); // 应该还是 'Item B'
console.log('Cloned Item B Name:', clonedArray[1].name); // 应该是 'Item C'
console.log('Original Item A Date Year:', originalArray[0].createdAt.getFullYear()); // 应该还是当前年份
console.log('Cloned Item A Date Year:', clonedArray[0].createdAt.getFullYear()); // 应该是 2000
console.log('Original Item B Func:', originalArray[1].func); // Lodash会丢失函数,这里会是 undefined对于那些对性能有极致要求,或者数据结构极其特殊,且不想引入第三方库的场景,你也可以考虑自己实现一个递归的深度克隆函数。但这通常比较复杂,需要处理各种边缘情况,比如循环引用,不同类型的对象(数组、日期、正则、Map、Set等),以及原型链的继承问题。一般情况下,不建议自己造这个轮子。
这其实是 JavaScript 中一个非常基础但也容易让人迷惑的概念:值类型和引用类型。当你用
const newArr = oldArr;
const newArr = [...oldArr];
所以,当你修改
newArr[0].name
newArr[0]
oldArr[0]
oldArr[0].name
JSON.parse(JSON.stringify())
首先,它会丢失函数。对象里的方法或者任何函数属性都会在序列化过程中被直接忽略。因为 JSON 压根就不支持存储函数。
const objWithFunc = {
name: 'Test',
greet: function() { console.log('Hello'); }
};
const cloned = JSON.parse(JSON.stringify(objWithFunc));
console.log(cloned.greet); // undefined其次,undefined
Symbol
BigInt
const objWithSpecial = {
a: undefined,
b: Symbol('sym'),
c: 10n // BigInt
};
const cloned = JSON.parse(JSON.stringify(objWithSpecial));
console.log(cloned); // {} - 什么都没了再来,Date
Date
const objWithDate = {
eventDate: new Date()
};
const cloned = JSON.parse(JSON.stringify(objWithDate));
console.log(cloned.eventDate); // "2023-10-27T08:30:00.000Z" (一个字符串)
console.log(cloned.eventDate instanceof Date); // false还有,RegExp
{}const objWithRegExp = {
pattern: /abc/g
};
const cloned = JSON.parse(JSON.stringify(objWithRegExp));
console.log(cloned.pattern); // {}最后,它不能处理循环引用。如果你的对象结构中存在循环引用(比如 A 引用 B,B 又引用 A),
JSON.stringify()
TypeError: Converting circular structure to JSON
所以,虽然
JSON.parse(JSON.stringify())
Lodash 的
_.cloneDeep
一个非常值得关注的,是现代浏览器和 Node.js(v17+)提供的原生 API:
structuredClone()
JSON.parse(JSON.stringify())
Date
以上就是js 如何使用cloneDeep深度克隆对象数组的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号