前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
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.stringify 处理undefined 函数 Symbol
JavaScript数据处理

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

要看它们出现在哪:在对象里,值为 undefined、函数或 Symbol 的属性会连键一起消失;在数组里,这些元素会变成 null,保住后面元素的位置;直接 JSON.stringify(undefined),返回的是 undefined 本身,不是字符串。

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

同一个值,看它出现在哪

  1. 对象属性值是 undefined、函数或 Symbol 时,这个键值对被跳过
  2. 数组元素写成 null,数组长度和其他元素的下标不变
  3. 顶层值JSON.stringify 返回 undefined,拿它当请求体会出问题

属性被删掉和属性值为 null 在后端看来完全不同。PATCH 接口里前者通常表示「不修改」,后者表示「清空」,默认序列化会把你本想清空的 undefined 字段变成「不修改」。

核心回答

先记住这个答案

JSON.stringify 只输出 JSON 能表示的值,undefined、函数和 Symbol 在 JSON 里都没有对应的类型,处理方式取决于它们的位置。在对象里,属性连同键名一起被删掉,因为 JSON 对象里少一个成员不会破坏结构。在数组里,这些元素会被写成 null,因为删掉会让后面元素的下标全部前移。如果直接传这三类值,JSON.stringify 没有东西可输出,返回 undefined,注意不是字符串 "undefined"。

  • 对象里:属性连键一起被删掉
  • 数组里:变成 null,保留下标
  • 顶层:返回 undefined,不是字符串
  • Symbol 作为键时,这个属性也会被忽略

同一组值放在三个位置

把同样的三个值分别放进对象、数组,以及直接传给 JSON.stringify。

对象删属性,数组保位置JavaScript
const fn = () => 1
const token = Symbol('token')

console.log(JSON.stringify({ a: undefined, b: fn, c: token, d: 0 }))
console.log(JSON.stringify([undefined, fn, token, 0]))
console.log(JSON.stringify(undefined))
console.log(typeof JSON.stringify(fn)) // 顶层返回的不是字符串
查看输出与解释
{"d":0}
[null,null,null,0]
undefined
undefined

第一行只剩下能序列化的 d,其他三个属性连键名都没有了。第二行数组长度还是 4,前三个位置用 null 占着,这样 0 仍然在下标 3。第三、四行说明顶层传入这些值时返回的是 undefined,拿它当 fetch 的 body,等于没有请求体,后端拿到的是空内容;要是再和别的字符串拼接,又会变成 "undefined" 这几个字母。 为什么对象和数组处理不同?对象的成员是按名字访问的,少一个不影响别的。数组靠顺序表达数据,删掉第一个元素,原来的第二个就变成了第一个,数据就错位了,所以只能用 null 占位。

项目里真正会踩的坑

面试时说出上面的规则只是第一步。更重要的是知道它在业务里会造成什么问题。

PATCH 接口和其他细节JavaScript
const patch = { nickname: undefined, avatar: null }
console.log(JSON.stringify(patch)) // nickname 被删掉了

// 需要保留字段时,用 replacer 把 undefined 转成 null
console.log(JSON.stringify(patch, (key, value) => (value === undefined ? null : value)))

const id = Symbol('id')
console.log(JSON.stringify({ [id]: 1, a: 1 })) // Symbol 作为键也会被忽略
console.log(JSON.stringify([, 1])) // 稀疏数组的空位也变成 null
查看输出与解释
{"avatar":null}
{"nickname":null,"avatar":null}
{"a":1}
[null,1]

很多 PATCH 接口的约定是:字段不传表示不修改,传 null 表示清空。表单里用户清空了昵称,前端状态里是 undefined,序列化后字段直接消失,后端以为不用改,昵称就没被清掉。反过来,如果后端把 null 当成清空,而你用 replacer 把所有 undefined 都转成 null,又可能清掉了本来不想动的字段。所以提交前要按接口约定,明确每个字段是「不传」还是「传 null」。 Symbol 作为属性键时,不管值是什么,这个属性都不会被序列化,因为 JSON 的键只能是字符串。稀疏数组里的空位和显式写 undefined 的元素,输出都是 null。

别用 stringify 结果判断空对象
JSON.stringify(obj) === '{}' 看起来能判断空对象,但 { a: undefined } 和 { [Symbol()]: 1 } 也会得到 '{}',Map、Set 和正则对象同样如此。判断空对象用 Object.keys(obj).length === 0,需要把 Symbol 键也算上就用 Reflect.ownKeys。
回答前,多想一步

容易答错的地方

以为所有位置都会变成 null
只有数组元素会变成 null。对象里是整个属性消失,顶层是返回 undefined。三种情况要分开记。
以为 JSON.stringify(undefined) 返回 'undefined'
它返回的是 JavaScript 的 undefined,对它取 typeof 结果是 'undefined',但它不是字符串。字符串 "undefined" 是另一个东西,只在你把这个返回值再拼接或者强转时才会出现。
试着用自己的话回答

面试官还会怎么问?

函数和 Symbol 在对象里被删掉,Date 和 Map 呢?

Date 有 toJSON() 方法,会被转成 ISO 字符串。Map 和 Set 没有可枚举的自有属性,会被序列化成 {},内容全丢但属性还在,比 undefined 更隐蔽。RegExp 也会变成 {}。

对象的 toJSON() 返回 undefined 会怎样?

和值本身是 undefined 一样处理。这个对象作为属性时,属性会被删掉;作为数组元素时变成 null;作为顶层值时 JSON.stringify 返回 undefined。

怎么让函数也能被序列化?

JSON 设计上就不传代码,一般也不该传。确实有需要,可以在 replacer 里返回 value.toString() 得到源码字符串,但接收端要用 eval 或 new Function 才能还原,这有严重的安全风险。正确的做法是传数据,让接收端根据数据选择对应的逻辑。

从一道题,走向一组知识

把知识连起来

数据处理

正则的 s 标志是干什么的?和 m 标志有什么区别?

都是「一个规则在不同位置表现不同」的题,undefined 看位置决定去留,m 和 s 标志分别影响锚点和点号。

数据处理

带 g 的正则连续调用 test,为什么结果一会儿 true 一会儿 false?

两题都容易在「看起来没报错」时丢数据:一个是字段被静默删掉,一个是 lastIndex 没重置导致匹配被跳过。

参考资料

  • JavaScript:数据处理参考资料

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

本题目录
  1. 先记住这个答案
  2. 同一组值放在三个位置
  3. 项目里真正会踩的坑
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

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

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