我们使用js-joda LocalDate来表示模型中的各种日期,并将这些日期存储在sessionStorage中。是否有一种通用的首选方法来存储这些日期,以便它们可以序列化/反序列化,而无需向包含它们的每个对象添加特殊代码?
我们一直在使用标准的JSON.stringify
/JSON.parse
来执行此操作,但由于LocalDate
在字符串化时转换为 ISO 字符串,因此当我们解析它时,我们会丢失其LocalDate
类型。
如此处所示
以下是摘要:
const myObj = { a: "thing", d: LocalDate.parse('2019-01-20') };
const stringified = JSON.stringify(myObj);
const parsed = JSON.parse(stringified);
// this fails because d is no longer a LocalDate
console.log(parsed.d.year());
我们现在的解决方法是,我们为任何包含 LocalDate 的类提供了自定义反序列化程序,但这似乎有点笨拙。
为此寻求更清洁的解决方案。也许我们可以为 LocalDate 制作一个通用序列化程序,它输出与 console.log 中的%o
修饰符相同的内容?
mydate -> serialize -> "LocalDate { _year: 2019, _month: 1, _day: 20}"
在我们这样做之前,我正在寻找这是否已经干净利落地完成,或者我是否只是错过了一些明显的东西。
回答我自己的问题。
我很惊讶它没有出现,但解决方案就在JSON.stringify
和JSON.parse
的定义中。
这篇文章为我指出了当我需要用地图做同样的事情时的解决方案。
JSON.parse(text[, reviver])
JSON.stringify(value[, replacer[, space]])
我需要添加替换器和齐磊来执行自定义序列化:
function myReviver(key: string, value: any) {
if (value === undefined) return undefined;
if (value === null) return null;
if (typeof value === 'object') {
switch (value.dataType) {
case 'LocalDate':
return LocalDate.parse(value.value);
case 'LocalTime':
return LocalTime.parse(value.value);
case 'LocalDateTime':
return LocalDateTime.parse(value.value);
case 'Period':
return Period.parse(value.value);
}
}
return value;
}
function myReplacer(key, value) {
const originalObject = this[key];
if (originalObject instanceof LocalDate) {
return {
dataType: 'LocalDate',
value: originalObject.toJSON()
};
} else if (originalObject instanceof LocalTime) {
return {
dataType: 'LocalTime',
value: originalObject.toJSON()
};
} else if (originalObject instanceof LocalDateTime) {
return {
dataType: 'LocalDateTime',
value: originalObject.toJSON()
};
} else if (originalObject instanceof Period) {
return {
dataType: 'Period',
value: originalObject.toJSON()
};
} else {
return value;
}
}
每当我调用 stringify 或解析时,我都会添加上述函数作为它们的替换器/恢复器。
JSON.stringify(mystuff, myReplacer);
JSON.parse(mystuff, myReviver);