主题
JavaScript 序列化与反序列化:方法、性能与最优方案
在 JavaScript 中,序列化(Serialization) 是将对象转换为字符串或二进制数据的过程,而 反序列化(Deserialization) 则是将这些数据还原为对象的过程。这一机制广泛用于 本地存储、网络传输、缓存同步、数据深拷贝 等场景。
本文将系统地比较几种常见方法的功能、性能、优缺点,并结合 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 最优序列化组合。”
相关文章:深拷贝与序列化:将对象转为字符串并还原