前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库JSON.parse reviver 解析日期字符串
JavaScript数据处理

接口返回的日期是字符串,怎么用 JSON.parse 的 reviver 转回 Date?

Date 被 JSON.stringify 之后就是一个 ISO 字符串,JSON.parse 不会自动认出它。给 JSON.parse 传第二个参数 reviver,它会对每个属性调用一次,你可以只在约定的日期字段上返回 new Date(value)。注意默认分支一定要 return value,返回 undefined 会把属性删掉。

前端进阶之旅 · 一题精讲更新于 2026.09.29
JavaScript#数据处理
先看核心答案读代码示例
理解线索

先解析,再按约定恢复类型

  1. JSON.parse先按 JSON 规则生成对象、数组、字符串和数字
  2. reviver从里到外遍历每个属性,用返回值替换原值
  3. 字段约定只有约定为日期的字段才转成 Date,其他保持原样

最后一次调用的 key 是空字符串,value 是整个解析结果。在这一次返回 undefined,整个 JSON.parse 的结果就是 undefined。

核心回答

先记住这个答案

Date 经过 JSON.stringify 会调用 toISOString() 变成字符串,JSON 本身没有日期类型,所以 JSON.parse 回来还是字符串。JSON.parse(text, reviver) 的第二个参数是一个回调,解析完成后会对每个属性调用一次,参数是 key 和 value,返回值会替换原来的值。恢复日期的做法是:只在约定的日期字段上把字符串转成 Date,其他字段原样返回。reviver 的调用顺序是从里到外,先处理最深的属性,最后以空字符串为 key 处理根对象;返回 undefined 会删掉这个属性。

  • JSON 里的日期只是字符串,不会自动变回 Date
  • reviver 从最深的属性开始,最后处理根
  • 返回 undefined 会删掉这个属性
  • 按字段名转换,别见到像日期的字符串就转

按字段恢复日期,并检查日期是否真实存在

接口返回的对象里有创建时间、过期时间,还有一个长得像日期的普通标签。只转该转的。

用字段名限定转换范围JavaScript
const text =
  '{"createdAt":"2026-09-10T08:30:00.000Z","label":"2026-09-10","expireAt":"2026-02-30T00:00:00.000Z"}'
const DATE_FIELDS = new Set(['createdAt', 'expireAt'])

function toDate(value) {
  const date = new Date(value)
  // 读回来和原文对不上,说明日期被引擎挪过了,比如 2 月 30 日
  return !Number.isNaN(date.getTime()) && date.toISOString() === value ? date : null
}

const data = JSON.parse(text, (key, value) =>
  DATE_FIELDS.has(key) && typeof value === 'string' ? toDate(value) : value
)
console.log(data.createdAt instanceof Date, typeof data.label, data.expireAt)
查看输出与解释
true string null

createdAt 变成了 Date。label 虽然长得像日期,但不在字段列表里,保持字符串。 expireAt 是 2 月 30 日,一个不存在的日期。在 Chrome 和 Node 里,new Date('2026-02-30T00:00:00.000Z') 不会得到 Invalid Date,而是被挪到 3 月 2 日,只检查 Number.isNaN(date.getTime()) 拦不住。所以 toDate 多做了一步:把 Date 转回 ISO 字符串,和原文对比,对不上就说明被挪过了。这个校验要求接口统一用 toISOString() 的标准格式,实际项目里通常和后端约定好。

为什么不用正则匹配所有日期字符串
有人会写 /^\d{4}-\d{2}-\d{2}/.test(value) 就转 Date,这会把版本号、订单编号、只有日期的生日字段都误转。生日「1990-05-20」转成 Date 后是 UTC 零点,在美洲时区显示成 5 月 19 日。什么字段是时间点,应该由接口约定决定,而不是看字符串长什么样。

调用顺序和返回值规则

reviver 的两条规则最容易踩坑:从里到外调用,返回 undefined 删属性。

观察调用顺序和删除效果JavaScript
const order = []
JSON.parse('{"a":{"b":1,"c":[2]},"d":3}', (key, value) => {
  order.push(key === '' ? '(root)' : key)
  return value
})
console.log(order.join(' -> '))

const safe = JSON.parse('{"a":1,"password":"x"}', (key, value) =>
  key === 'password' ? undefined : value // 返回 undefined,属性被删
)
console.log(JSON.stringify(safe))

console.log(JSON.parse('{"a":1}', (key, value) => { if (key === 'a') return value * 2 }))
查看输出与解释
b -> 0 -> c -> a -> d -> (root)
{"a":1}
undefined

第一行是调用顺序。b 和 c 比 a 先处理,数组元素的 key 是字符串 '0',根对象最后处理,key 是空字符串。所以父级回调拿到的是子属性已经处理完的结果,可以在父级把恢复好的字段组装成领域对象。 第三行是最常见的 bug。回调只在 key === 'a' 时有返回值,其他情况函数默认返回 undefined。轮到根对象时也返回了 undefined,整个解析结果就没了。写 reviver 的第一件事,就是在最后加上 return value。

回答前,多想一步

容易答错的地方

以为 JSON.parse 能自动识别日期
JSON 只有字符串、数字、布尔、null、对象和数组六种类型。日期序列化后就是字符串,解析时不会有任何特殊处理。
忘记默认 return value
箭头函数只写了条件分支,其他属性全部返回 undefined,被逐个删掉,最后连根对象也没了。用三元表达式或者在函数末尾统一 return value 能避免。
试着用自己的话回答

面试官还会怎么问?

reviver 里的 this 指向什么?

用普通函数写时,this 是当前属性所在的对象,可以用它读取同级的其他字段,比如根据 this.type 决定怎么转换。箭头函数没有自己的 this,拿不到这个对象。

字段很多、结构很深时,还用 reviver 吗?

reviver 适合「所有叫 createdAt 的字段都转 Date」这种简单统一的规则。复杂接口更适合先 JSON.parse,再用 zod 这类 schema 库校验并转换,出错时能明确告诉你是哪个字段、什么原因,而不是悄悄变成 null。

只有日期没有时间的字段,比如生日,要转成 Date 吗?

一般不转。Date 表示的是一个时间点,生日是一个日历日期,转成 Date 就要选一个时区的零点,换个时区显示就可能差一天。保持 YYYY-MM-DD 字符串,只在显示时格式化,是更稳的做法。

从一道题,走向一组知识

把知识连起来

数据处理

JSON.stringify 的第二个参数有什么用?怎么用它过滤和转换属性?

reviver 是解析时的回调,replacer 是序列化时的回调,两者参数一样,通常成对出现。

数据处理

对象里有 undefined、函数和 Symbol,JSON.stringify 之后它们去哪了?

reviver 返回 undefined 会删属性,replacer 返回 undefined 也会删,都和 JSON 里「undefined 表示不存在」的规则有关。

参考资料

  • JavaScript:数据处理参考资料

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 按字段恢复日期,并检查日期是否真实存在
  3. 调用顺序和返回值规则
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑