axelu.me
JavaScript 中的克隆
介绍 JavaScript 中几种常见的对象克隆方法,包括浅拷贝和深拷贝,以及它们的优缺点和适用场景。
2021-07-13
JavaScript 中的克隆
介绍 JavaScript 中几种常见的对象克隆方法,包括浅拷贝和深拷贝,以及它们的优缺点和适用场景。
4 min read
created on 2021-07-13
/ updated on 2024-08-05
#javascript
#clone
JavaScript 中的克隆
1. 浅拷贝选手:Object.assign()
和展开运算符 ...
这两位是浅拷贝界的明星选手。它们快速、简单,而且语法超级优雅。
const original = { name: 'Tom', age: 18 };
const copy1 = Object.assign({}, original);
const copy2 = { ...original };
优点:
- 使用简单,一行代码搞定
- 性能好,速度快
缺点:
- 只能拷贝一层,遇到嵌套对象就傻眼了
- 对于引用类型,拷贝的是引用,不是真正的复制
适用场景: 当你只需要复制简单对象,没有嵌套结构时,它们就是你的最佳选择。
2. 深拷贝界的老前辈:JSON.parse(JSON.stringify())
这个方法就像是深拷贝界的”老顽固”,有点笨重,但是效果还不错。
const original = { name: 'Tom', hobbies: ['reading', 'swimming'] };
const copy = JSON.parse(JSON.stringify(original));
优点:
- 可以处理嵌套对象
- 实现简单,无需额外库
缺点:
- 性能较差,特别是对于大对象
- 无法处理函数、undefined、Symbol 等特殊类型
- 会丢失原型链
适用场景: 当你需要快速实现深拷贝,并且对象结构不太复杂时,可以考虑这个方法。
3. 深拷贝新秀:structuredClone()
这位是深拷贝界的新星,带着现代化的装备华丽登场。structuredClone() 是一个相对较新的 JavaScript 全局方法,专门用于创建深拷贝。它于 2022 年成为 ECMAScript 标准的一部分,现在在现代浏览器和 Node.js 中得到广泛支持。
const original = { name: 'Tom', hobbies: ['reading', 'swimming'] };
const copy = structuredClone(original);
优点:
- 可以处理循环引用
- 支持大多数数据类型,包括 Map、Set 等
- 性能通常比 JSON 方法好
缺点:
- 不支持函数的克隆
- 在旧版浏览器中可能不支持
适用场景: 当你需要克隆复杂对象,并且不涉及函数克隆时,这是你的最佳选择。
4. 万能选手:自定义深拷贝函数
如果你想要完全掌控,那就自己动手丰衣足食吧!
function deepClone(obj) {
if (obj === null || typeof obj !== 'object') {
return obj;
}
if (Array.isArray(obj)) {
return obj.map(deepClone);
}
return Object.fromEntries(
Object.entries(obj).map(([key, value]) => [key, deepClone(value)])
);
}
优点:
- 可以完全控制克隆过程
- 可以处理各种特殊情况
缺点:
- 实现复杂,需要考虑很多边界情况
- 可能存在 bug,需要充分测试
适用场景: 当你需要处理特殊需求,或者其他方法都无法满足你时,可以考虑自己实现。
总结
- 如果你只是克隆简单对象,用展开运算符或
Object.assign()
就够了。 - 需要深拷贝但不想费脑子?
structuredClone()
是你的好朋友。 - 对象里有函数或者其他特殊类型?可能需要自定义函数或第三方库了。
JSON.parse(JSON.stringify())
虽然有点笨,但在某些简单场景下还是挺实用的。
记住,没有一种方法是完美的,选择最适合你当前需求的那个就好。编程就像做菜,要根据食材(数据)和口味(需求)来选择烹饪方法(克隆方式)。