json.stringify()对不可序列化值采取静默处理:undefined/函数/symbol属性被忽略,数组中转null;date/regexp等调用tojson()或返回{};循环引用抛typeerror;bigint/arraybuffer原生不支持需手动转换。

JavaScript 的 JSON.stringify() 在遇到无法序列化的值时,不会报错,而是按规则静默跳过或转换,这种“宽容但有原则”的行为容易引发隐性 bug。
undefined、函数、Symbol 类型被完全忽略
当对象属性的值是 undefined、函数或 Symbol 时,该属性在序列化结果中直接消失(不保留键名,也不转为 null)。
-
JSON.stringify({ a: undefined, b: () => {}, c: Symbol('x') })→"{}" - 数组中出现这些值时,对应位置变成
null(仅限数组索引项):JSON.stringify([1, undefined, 2])→"[1,null,2]"
Date、RegExp、Map、Set 等内置对象被转为空对象或调用 toJSON()
多数内置对象默认没有 toJSON() 方法,序列化结果为 {};但 Date 和 RegExp 是例外:
-
Date实例会调用其toJSON(),返回 ISO 字符串:JSON.stringify(new Date(2023, 0, 1))→"\"2023-01-01T00:00:00.000Z\"" -
RegExp默认无toJSON(),结果为{};可手动添加:/abc/.toJSON = () => 'abc' -
Map和Set没有toJSON(),直接转成{},需先转为普通对象或数组再序列化
循环引用会抛出 TypeError
如果对象存在自引用或相互引用,JSON.stringify() 会立即报错:TypeError: Converting circular structure to JSON。
- 例如:
const obj = {}; obj.self = obj; JSON.stringify(obj); - 解决方式:使用
replacer函数过滤掉循环引用字段,或借助第三方库(如flatted)支持循环结构
BigInt 和 ArrayBuffer 等新类型不被原生支持
JSON.stringify() 原生不处理 BigInt 和 ArrayBuffer,直接抛错:
-
JSON.stringify({ x: 123n })→TypeError: Do not know how to serialize a BigInt -
JSON.stringify(new Uint8Array([1,2,3]))→ 同样报错 - 需显式转换:
BigInt转字符串,TypedArray转普通数组:Array.from(uint8)
理解这些边界行为,能帮你提前规避数据丢失、意外空对象或运行时错误。实际开发中建议配合 replacer 或封装安全序列化函数做兜底。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











