使用自定义接收器处理JSON日期序列化/反序列化的问题排查
问题描述
我希望自定义日期的序列化(serialize)和反序列化(deserialize)逻辑,于是尝试通过自定义接收器(replacer函数)在JSON.stringify()过程中拦截日期对象。编写了如下serialize函数:
function serialize(data) { if (data === undefined) { return JSON.stringify('__undef__') } if (data instanceof Date) { return JSON.stringify({ _t: 'dt', v: data.getTime() }) } return JSON.stringify(data, (_, value) => { if (value === undefined) { return '__undef__' } if (value instanceof Date) { return { _t: 'dt', v: data.getTime() } } return value }) } console.log(serialize(new Date(2024, 7, 4))); // {"_t":"dt","v":1722729600000} console.log(serialize([undefined, new Date(2024, 7, 4)])); // ["__undef__","2024-08-04T00:00:00.000Z"]
但发现处理包含日期的数组时,接收器未拦截日期格式,导致日期被序列化为默认格式而非自定义格式。请问哪里出错了?
错误原因
- replacer函数变量误用:你在replacer里写了
data.getTime(),但这里的data是外层函数接收的整个数组,不是当前遍历到的日期对象。调用数组的getTime()会抛出错误,而JSON.stringify遇到replacer报错时会忽略自定义逻辑,直接用默认规则序列化日期,导致出现ISO格式字符串。 - 冗余的前置判断:开头单独判断
data === undefined和data instanceof Date的逻辑完全可以整合到replacer函数中,让所有场景的序列化逻辑统一,避免代码重复。
修正后的代码
function serialize(data) { return JSON.stringify(data, (_, value) => { if (value === undefined) { return '__undef__'; } if (value instanceof Date) { return { _t: 'dt', v: value.getTime() }; } return value; }); } console.log(serialize(new Date(2024, 7, 4))); // {"_t":"dt","v":1722729600000} console.log(serialize([undefined, new Date(2024, 7, 4)])); // ["__undef__",{"_t":"dt","v":1722729600000}]
解释
- 移除冗余的前置判断,所有逻辑统一交给replacer函数处理,包括顶层的undefined和日期对象。
- 将replacer里的
data.getTime()改为value.getTime(),确保取到的是当前遍历到的日期对象的时间戳。 - 现在无论是单独的日期、包含日期的数组还是其他嵌套结构,都能正确应用自定义序列化规则。
内容的提问来源于stack exchange,提问作者eakl
相关产品推荐
相关产品推荐

