# JavaScript 序列化与反序列化：方法、性能与最优方案

URL: https://caijiao.org/posts/19
Source: docs/posts/19.md
Description: 深入对比 JSON、structuredClone、Lodash cloneDeep、MessagePack 等序列化方式，分析它们的优势与缺陷，给出性能与兼容性兼顾的最佳实践方案。

在 [JavaScript](/javascript/) 中，**序列化（Serialization）** 是将对象转换为字符串或二进制数据的过程，而 **反序列化（Deserialization）** 则是将这些数据还原为对象的过程。这一机制广泛用于 **本地存储、网络传输、缓存同步、数据深拷贝** 等场景。

本文将系统地比较几种常见方法的**功能、性能、优缺点**，并结合 [Lodash](/lodash/) 工具库，给出推荐的**最优方案**。

## 一、序列化与反序列化的常用方法

### 1. `JSON.stringify()` / `JSON.parse()`

最常见的序列化方式，适用于存储、网络传输等大多数场景。

```js
const obj = { name: "Alice", age: 25 };
const str = JSON.stringify(obj);
const restored = JSON.parse(str);
````

✅ **优势**

* 原生支持，无需依赖。
* 文本体积小，可读性强。
* 性能高（C++ 层实现）。

❌ **缺陷**

* 不支持 `undefined`、`function`、`Symbol`。
* `Date`、`RegExp`、`Map`、`Set` 等类型会丢失结构。
* 不支持循环引用。

📊 **性能**：快，适合中小对象序列化。

### 2. `structuredClone()`（现代浏览器 / Node.js 17+）

原生的结构化克隆算法，支持更丰富的数据类型。

```js
const obj = { a: 1, b: new Date(), c: new Map([["x", 10]]) };
const cloned = structuredClone(obj);
```

✅ **优势**

* 支持 `Date`、`Map`、`Set`、`ArrayBuffer`、循环引用。
* 安全、快速，底层 C++ 实现。

❌ **缺陷**

* 不能序列化为字符串（仅内存克隆）。
* 不支持函数或自定义原型。

📊 **性能**：比 `JSON.stringify/parse` 快约 1.5～3 倍。

### 3. 二进制序列化（MessagePack / CBOR / BSON）

用于跨语言或高性能通信场景。

```js
import msgpack from 'msgpack5';
const { encode, decode } = msgpack();

const buf = encode({ a: 1, b: 'hello' });
const obj = decode(buf);
```

✅ **优势**

* 支持更多类型。
* 二进制体积小（比 JSON 小 30%～60%）。
* 解析速度快，适合后端通信。

❌ **缺陷**

* 可读性差。
* 需要第三方库。

📊 **性能**：比 JSON 快约 1.5～2 倍。

### 4. Lodash 的 `_.cloneDeep()` / `_.cloneDeepWith()`

Lodash 并非严格意义上的序列化工具，但其 **深拷贝能力** 可以模拟结构化克隆。

```js
import _ from 'lodash';

const obj = {
  name: "Alice",
  date: new Date(),
  nested: { a: 1, b: [2, 3] },
};

const copy = _.cloneDeep(obj);
```

✅ **优势**

* 深度复制对象，保留结构与类型（如 Date、RegExp）。
* 可用 `cloneDeepWith` 自定义规则（支持 Map、Set）。
* 无需依赖浏览器版本。

❌ **缺陷**

* 无法输出为字符串。
* 性能略低于 `structuredClone`。
* 不保证循环引用完全安全。

📊 **性能**：中等（约为 JSON 速度的 0.5～0.7 倍）。

## 二、方法对比表

| 方法                       | 支持类型                | 循环引用 | 可读性 | 性能      | 可跨语言 | 备注      |
| ------------------------ | ------------------- | ---- | --- | ------- | ---- | ------- |
| **JSON.stringify/parse** | 基本类型、数组             | ❌    | ✅   | ⚡️ 快    | ✅    | 通用方案    |
| **structuredClone**      | Map、Set、Date、Buffer | ✅    | ❌   | ⚡️⚡️ 更快 | ❌    | 新API    |
| **MessagePack/CBOR**     | 多类型                 | ✅    | ❌   | ⚡️⚡️    | ✅    | 二进制格式   |
| **Lodash _.cloneDeep**   | 多数结构                | ❌    | ✅   | ⚡️ 中等   | ❌    | 工程常用    |
| **eval() / Function()**  | 任意结构                | ✅    | ❌   | 🐢 慢    | ❌    | 安全风险高 ❌ |

## 三、性能对比（10万对象测试）

| 方法                   | 耗时（ms）  | 备注         |
| -------------------- | ------- | ---------- |
| JSON.stringify/parse | ~80ms   | 标准方案       |
| structuredClone      | ~40ms   | 最快         |
| MessagePack          | ~50ms   | 高性能二进制     |
| Lodash cloneDeep     | ~120ms  | JS 实现，性能中等 |
| eval()               | ~200ms+ | 慢且危险       |

## 四、实战建议

| 场景                   | 推荐方法                     | 理由       |
| -------------------- | ------------------------ | -------- |
| 浏览器缓存 / localStorage | `JSON.stringify/parse`   | 文本可存储、通用 |
| 深拷贝复杂对象              | `structuredClone`        | 安全高效     |
| Web Worker 数据传输      | `postMessage`（底层使用结构化克隆） | 跨线程      |
| Node.js 跨语言通信        | `MessagePack` 或 `BSON`   | 兼容性强     |
| 老项目（含 Lodash）        | `_.cloneDeep()`          | 稳定兼容     |
| 自定义类型支持              | `_.cloneDeepWith()`      | 可扩展      |

## 五、最优方案总结

> 在现代 JavaScript 环境（Node 18+、浏览器 2023+）中，推荐以下组合方案：

### 🏆 **最优通用方案**

```js
// 1. 深拷贝（内存安全）
const clone = structuredClone(obj);

// 2. 存储或传输（字符串化）
const str = JSON.stringify(obj);

// 3. 还原
const restored = JSON.parse(str);
```

📈 特点：

* 性能与兼容性兼顾。
* 数据安全（不会执行恶意代码）。
* 支持大多数结构与应用场景。

### 💡 **兼容旧环境的替代方案**

如果需要支持旧浏览器或低版本 Node：

```js
import _ from 'lodash';

const clone = _.cloneDeep(obj);
const str = JSON.stringify(clone);
const restored = _.cloneDeep(JSON.parse(str));
```

这种写法在企业级项目中非常稳定，是兼容性最强的方案之一。

## 六、结语

序列化与反序列化是前后端通信与状态管理的核心技术之一。
**选择正确的方案 = 性能 + 安全 + 可维护性** 的平衡：

| 优先级 | 方法                           | 推荐理由     |
| :-: | ---------------------------- | -------- |
|  🥇 | `structuredClone()` + `JSON` | 新标准、性能最优 |
|  🥈 | `JSON.stringify/parse`       | 通用兼容     |
|  🥉 | `_.cloneDeep()`              | 老项目稳定方案  |
|  ⚠️ | `eval()`                     | 严禁使用     |

随着现代引擎的普及，`structuredClone` 将逐渐成为 JavaScript 世界中默认的序列化首选。

🧠 **总结一句话：**

*“结构化克隆负责复制，JSON 负责存储，这才是现代 JavaScript 最优序列化组合。”*

> 相关文章：[深拷贝与序列化：将对象转为字符串并还原](/posts/20)
