json不支持function和undefined因其仅定义六种数据类型;函数被直接跳过,undefined在对象中被删除、数组中转为null;这是规范设计而非缺陷,需用structuredclone等替代方案实现完整克隆。

因为 JSON 本身是一种数据交换格式,不是 JavaScript 对象的完整序列化协议。它只定义了六种合法类型:字符串、数字、布尔值、null、数组、对象。而 Function 和 undefined 都不在其中。
Function 为什么被丢弃
JSON.stringify 在遇到函数时,既不报错也不保留——直接跳过该属性。例如:
-
{ fn: () => 'hi' }经JSON.stringify后变成{} - 方法、箭头函数、事件处理器、getter/setter 中的函数逻辑全部消失
- 这不是 bug,是规范强制行为:JSON 不描述行为,只承载数据
Undefined 为什么被忽略
undefined 在 JSON 中没有对应表示方式,引擎按规则处理:
- 对象中
{ a: undefined }→ 序列化后该键彻底消失 - 数组中
[1, undefined, 3]→ 变成[1, null, 3](唯一“降级”情形) - 顶层值为
undefined→JSON.stringify(undefined)返回undefined,导致后续JSON.parse报错
这不是技术缺陷,而是边界清晰的设计选择
JSON 的目标是跨语言、跨平台的数据传输,不是 JS 对象快照。它主动排除不可序列化的值,避免歧义和兼容性风险。如果你需要保留函数或 undefined,说明你真正需要的不是“JSON 拷贝”,而是“JS 对象克隆”——那就得换方案。
能真正保留它们的替代方式
- structuredClone():现代环境首选,支持 undefined、Date、Map、Set、RegExp 等,但函数仍只复制引用(不新建)
-
手写递归 clone:用
Reflect.ownKeys()遍历所有键(含 Symbol),对typeof value === 'function'或value === undefined做显式保留 -
Lodash + customizer:通过
_.cloneDeep(obj, (val) => typeof val === 'function' ? val : undefined)控制函数去留 -
预处理转义:拷贝前把 undefined 替换成
null或占位符(如"__undefined__"),再还原
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











