我不知道如何在 JS/TS 中创建深度克隆

开发 前端
在JavaScript和TypeScript中实现无突变的深度克隆可能比想象的更复杂。展开运算符和Object.create()​虽然常用,但不适合深度克隆。JSON.parse(JSON.stringify())​对于简单对象是一个快速有效的解决方案,而lodash.deepClone则是处理复杂数据结构的理想选择。

在JavaScript和TypeScript开发中,对象的深度克隆是一个常见但容易被误解的话题。本文将探讨几种常用的克隆方法,揭示它们的局限性,并介绍真正有效的深度克隆技术。

常见误区:展开运算符和Object.create()

许多开发者习惯使用展开运算符{...}或Object.create()来克隆对象,但这些方法实际上只能进行浅拷贝。

展开运算符的局限性:

const original = { name: "John", address: { city: "New York" } };
const clone = { ...original };

clone.address.city = "Los Angeles";
console.log(original.address.city); // 输出: "Los Angeles"

Object.create()的问题:

const original = { name: "John", address: { city: "New York" } };
const clone = Object.create(original);

clone.address.city = "Chicago";
console.log(original.address.city); // 输出: "Chicago"

这两种方法都无法实现真正的深度克隆,因为它们只复制了对象的顶层属性。

JSON.parse(JSON.stringify()):简单而有效

对于简单对象,JSON.parse(JSON.stringify())是一个有效的深度克隆方法:

const original = { name: "John", address: { city: "New York" } };
const clone = JSON.parse(JSON.stringify(original));

clone.address.city = "San Francisco";
console.log(original.address.city); // 输出: "New York"

然而,这种方法也有局限性。它无法处理函数、undefined、Infinity、NaN、正则表达式、Map和Set等复杂数据类型。

lodash.deepClone:全面而强大

对于需要处理复杂数据结构的场景,lodash.deepClone是一个更全面的解决方案:

import _ from 'lodash';

const original = {
  name: "John",
  address: { city: "New York" },
  skills: new Set(["JavaScript", "TypeScript"]),
  greet: function() { console.log("Hello!"); }
};

const clone = _.cloneDeep(original);

clone.address.city = "Boston";
clone.skills.add("React");

console.log(original.address.city); // 输出: "New York"
console.log(original.skills.has("React")); // 输出: false

lodash.deepClone能够正确处理嵌套对象、数组、函数,以及特殊的数据结构如Set和Map。

性能考虑

在性能方面,JSON.parse(JSON.stringify())通常对简单对象更快,而lodash.deepClone对复杂结构更可靠但速度较慢。

// 性能测试示例
const simpleObject = { a: 1, b: 2, c: 3 };
const complexObject = { /* 复杂的嵌套结构 */ };

console.time('JSON Simple');
JSON.parse(JSON.stringify(simpleObject));
console.timeEnd('JSON Simple');

console.time('Lodash Simple');
_.cloneDeep(simpleObject);
console.timeEnd('Lodash Simple');

console.time('JSON Complex');
JSON.parse(JSON.stringify(complexObject));
console.timeEnd('JSON Complex');

console.time('Lodash Complex');
_.cloneDeep(complexObject);
console.timeEnd('Lodash Complex');

结论

在JavaScript和TypeScript中实现无突变的深度克隆可能比想象的更复杂。展开运算符和Object.create()虽然常用,但不适合深度克隆。JSON.parse(JSON.stringify())对于简单对象是一个快速有效的解决方案,而lodash.deepClone则是处理复杂数据结构的理想选择。

理解这些方法的优缺点对于选择合适的克隆策略至关重要。在实际开发中,应根据具体需求和数据结构的复杂性来选择适当的深度克隆方法。通过掌握这些技巧,开发者可以更有效地处理对象克隆,提高代码的健壮性和可维护性。

责任编辑:武晓燕 来源: 大迁世界
相关推荐

2021-07-14 11:25:12

CSSPosition定位

2024-01-08 07:11:35

2021-12-29 11:38:59

JS前端沙箱

2020-07-16 08:32:16

JavaScript语言语句

2021-11-16 08:51:29

Node JavaScript变量类型

2020-12-14 07:51:16

JS 技巧虚值

2024-02-05 11:55:41

Next.js开发URL

2021-03-18 10:45:02

JavaScript数组运算符

2020-06-12 09:20:33

前端Blob字符串

2020-07-28 08:26:34

WebSocket浏览器

2024-03-27 12:35:12

2011-09-15 17:10:41

2009-12-10 09:37:43

2020-12-21 09:00:04

MySQL缓存SQL

2021-02-01 23:23:39

FiddlerCharlesWeb

2022-10-13 11:48:37

Web共享机制操作系统

2022-05-05 12:02:45

SCSS函数开发

2023-01-13 16:48:48

前端开发JavaScript

2018-04-04 12:05:04

Postgre数据planner

2010-08-23 09:56:09

Java性能监控
点赞
收藏

51CTO技术栈公众号