You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用自定义接收器处理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}]
解释
  1. 移除冗余的前置判断,所有逻辑统一交给replacer函数处理,包括顶层的undefined和日期对象。
  2. 将replacer里的data.getTime()改为value.getTime(),确保取到的是当前遍历到的日期对象的时间戳。
  3. 现在无论是单独的日期、包含日期的数组还是其他嵌套结构,都能正确应用自定义序列化规则。

内容的提问来源于stack exchange,提问作者eakl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 22:07:27