JavaScript (Node.js) 中的对象序列化:从 JSON 到二进制协议
序列化是将复杂的数据结构(对象、数组、Map、Set)转换为可保存到文件、通过网络传输或存储到数据库中的格式的过程。在 Node.js 中,这项任务尤为重要,因为服务器端应用程序通常处理大量数据、微服务和 WebSocket 连接。在本文中,我们将探讨 Node.js 环境中用于对象序列化的主要工具和库。
1. 内置 JSON:事实标准
JSON 模块在 Node.js 中无需安装额外包即可使用。它支持 JSON.stringify() 和 JSON.parse() 方法。
const user = { name: '安娜', age: 28, skills: ['JavaScript', 'Node.js'], active: true};
// 序列化const jsonString = JSON.stringify(user);console.log(jsonString);// {"name":"安娜","age":28,"skills":["JavaScript","Node.js"],"active":true}
// 反序列化const parsedUser = JSON.parse(jsonString);console.log(parsedUser.name); // 安娜优点:
- 人类可读的格式
- 所有环境均内置支持
- 易于调试
缺点:
- 不支持
undefined、BigInt、Date(会转换为字符串)、Map、Set - 比二进制格式慢
- 由于语法元素(引号、逗号)导致体积冗余
2. Node.js 中的 Buffer 和二进制序列化
对于高性能应用程序(游戏、金融数据、物联网),通常使用二进制格式。Node.js 为此提供了 Buffer 模块。
const buf = Buffer.alloc(8);buf.writeUInt32BE(123456, 0); // 写入 4 字节无符号整数buf.writeUInt32BE(789012, 4); // 第二个数字
console.log(buf); // <Buffer 00 01 e2 40 00 0c 08 14>
// 读取const a = buf.readUInt32BE(0); // 123456const b = buf.readUInt32BE(4); // 789012对于二进制格式的复杂对象序列化,最好使用专门的库。
3. Protocol Buffers (protobuf) — 高效的二进制序列化
protobuf.js 库允许根据 .proto 文件中定义的架构对对象进行序列化。这是 gRPC 和许多微服务架构中使用的标准。
安装:
npm install protobufjs使用示例:
const protobuf = require('protobufjs');
protobuf.load('user.proto').then(root => { const User = root.lookupType('userpackage.User');
const payload = { id: 1, name: '伊万', email: 'ivan@example.com' }; // 序列化 const errMsg = User.verify(payload); if (errMsg) throw Error(errMsg); const buffer = User.encode(payload).finish(); console.log('二进制缓冲区:', buffer);
// 反序列化 const decoded = User.decode(buffer); console.log('解码后:', decoded);});user.proto 文件:
syntax = "proto3";package userpackage;message User { int32 id = 1; string name = 2; string email = 3;}优点:
- 最佳性能
- 紧凑的体积(比 JSON 小 30-50%)
- 强类型和验证
- 跨平台
缺点:
- 需要定义架构 (.proto)
- 调试更复杂(二进制数据)
- 需要在服务之间同步架构