在Meteor框架中,EJSON(Extended JSON)是一个扩展了标准JSON的库,旨在支持更多的数据类型。标准JSON仅支持字符串、数字、布尔值、数组和对象等基本数据类型,而EJSON允许开发者在Meteor应用中传输更复杂的数据类型,例如Date
、Binary
数据,甚至是自定义对象。
EJSON的核心优势在于其可序列化和反序列化的能力,这使得Meteor在客户端和服务器之间传递复杂数据变得更加便捷和高效。
前文提要:开发环境的搭建 -全局安装或使用容器镜像 ;容器化开发环境下的meteor工程架构解析 ;运行在浏览器端的NoSQL数据库副本-MiniMongo介绍及其前后端数据实时同步示例;RPC方法注册及调用-更轻量的服务接口提供方式
在进行数据同步等时,往往需要向前端传递很多类型的数据,但对象的传输一般依赖于js runtime提供的JSON的stringify方法,但这个方法面对未定义toJSON方法的对象,例如Date时,会转化成一个字符串,反序列化parse时无法还原成Date,就可能存在一定的问题,或者每次都需要特殊处理。而Meteor则默认使用EJSON来序列化和反序列化,rpc返回的数据,调用rpc的参数等,都默认支持更多的类型-(例如二进制数据不需要转化成base64),所以了解下它的几个常用方法和如何自定义传输对象是很有用的--毕竟通过共享数据结构是可以提高开发效率的。
1 EJSON的接口
1.1 序列化EJSON.stringify
与标准的JSON.stringify
类似,EJSON.stringify
将EJSON对象序列化为字符串,但它能够处理更复杂的类型。
用法:
const obj = {
name: "Meteor", date: new Date() };
const ejsonString = EJSON.stringify(obj);
console.log(ejsonString);
1.2 反序列化EJSON.parse
类似于JSON.parse
,它从字符串中解析EJSON对象,支持对复杂类型的正确解析。
用法:
const ejsonString = '{"name":"Meteor","date":{"$date":1633029593494}}';
const parsedObj = EJSON.parse(ejsonString);
console.log(parsedObj);
1.3 对象克隆EJSON.clone
深度克隆一个EJSON对象,确保原始对象与副本完全独立。
用法:
const obj = {
name: "Meteor", date: new Date() };
const clonedObj = EJSON.clone(obj);
1.4 对象比较EJSON.equals
用于比较两个EJSON对象,支持对日期、二进制数据等复杂数据类型的深度比较。
用法:
const obj1 = {
name: "Meteor", date: new Date() };
const obj2 = EJSON.clone(obj1);
console.log(EJSON.equals(obj1, obj2)); // true
1.5 EJSON.isBinary
检查给定值是否为EJSON的二进制数据。
用法:
const binary = EJSON.newBinary(10);
console.log(EJSON.isBinary(binary)); // true
1.6 自定义类型注册EJSON.addType
用于定义和注册自定义类型,以便EJSON可以序列化和反序列化这些类型。
用法:
class CustomType {
constructor(value) {
this.value = value;
}
// 将自定义类型转换为普通对象
toJSONValue() {
return {
value: this.value };
}
// 从普通对象恢复自定义类型
static fromJSONValue(obj) {
return new CustomType(obj.value);
}
}
// 注册自定义类型
EJSON.addType('CustomType', CustomType);
2 自定义对象的传输
EJSON提供了内置的扩展机制,使得开发者可以轻松地定义自己的对象类型并在客户端与服务器之间传输。要实现自定义对象的传输,开发者需要遵循以下步骤:
2.1 创建自定义类型
创建一个自定义类,并实现两个核心方法:
toJSONValue()
:将对象的实例转换为普通的JSON结构,便于传输。fromJSONValue()
:从普通的JSON结构重建对象实例。
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
// 序列化为JSON
toJSONValue() {
return {
x: this.x, y: this.y };
}
// 反序列化为Point对象
static fromJSONValue(obj) {
return new Point(obj.x, obj.y);
}
}
2.2 注册自定义类型
通过EJSON.addType
将自定义类型注册到EJSON系统中。注册后的类型将自动支持序列化和反序列化。
EJSON.addType('Point', Point);
2.3 使用自定义对象传输
一旦自定义类型注册完成,开发者就可以像使用普通EJSON对象一样传输自定义对象。例如,在客户端创建一个Point
对象并传输到服务器端。
// 客户端
const point = new Point(5, 10);
const ejsonString = EJSON.stringify(point);
// 服务器端
const receivedPoint = EJSON.parse(ejsonString);
console.log(receivedPoint instanceof Point); // true
通过这种方式,Meteor的EJSON为复杂对象的传输提供了高度的灵活性和可扩展性,允许开发者根据项目需求自由定义自己的数据结构,并确保这些数据在客户端和服务器之间能够无缝传递。
3 结论
EJSON是Meteor框架中一个强大的工具,它扩展了JSON的功能,允许传输更多复杂的数据类型,同时支持自定义对象的序列化与反序列化。通过EJSON,Meteor应用可以轻松处理诸如日期、二进制数据等复杂类型,并提供了灵活的接口来定义和传输自定义对象,极大地增强了数据交互的能力。