JSON.stringify()可以转换哪些类型?
JSON.stringify()可以将一个 JS 对象或值转成 JSON 字符串。如果指定了 relpacer 函数可以选择性替换值;若 replacer 是个数组,可以选择性地仅转换包含数组指定的属性。
另外 JSON.stringify() 可以和 JSON.parse()配合来实现深拷贝,但不能拷贝值为 undefined 和循环引用的属性。
JSON.stringify()
可以将 JavaScript 值转换为符合 JSON 格式的字符串,但并非所有类型都能被直接转换。以下是支持的类型及其转换规则:
一、支持转换的类型
类型 | 转换结果 | 示例 |
---|---|---|
基本类型 | ||
string | 字符串(双引号包裹) | "hello" → "hello" |
number | 数值(包括整数、浮点数) | 42 → 42 ,3.14 → 3.14 |
boolean | true 或 false | true → true |
null | null | null → null |
对象类型 | ||
Object | 键值对(属性名用双引号包裹,值递归转换) | {a: 1} → {"a":1} |
Array | 数组(元素递归转换) | [1, "2"] → [1,"2"] |
Date | 调用 toISOString() 转换为 ISO 日期字符串 | new Date() → "2023-10-01T00:00:00.000Z" |
特殊处理 | ||
实现 toJSON() 的对象 | 优先调用 toJSON() ,返回结果再递归处理 | 自定义对象中定义 toJSON() 方法 |
二、无法转换或部分转换的类型
类型 | 转换结果/行为 | 示例 |
---|---|---|
undefined | 作为属性值时被忽略,单独转换返回 undefined | {a: undefined} → {} |
Function | 被忽略(属性值)或返回 undefined (单独转换) | function(){} → undefined |
Symbol | 被忽略(属性值)或返回 undefined (单独转换) | Symbol('foo') → undefined |
NaN /Infinity | 转换为 null | NaN → null ,Infinity → null |
特殊对象 | ||
Map /Set /WeakMap | 转换为空对象 {} (因没有可枚举的自有属性) | new Map([[1, 2]]) → {} |
RegExp | 转换为空对象 {} | /abc/g → {} |
Promise | 转换为空对象 {} | Promise.resolve() → {} |
循环引用 | 抛出 TypeError: Converting circular structure to JSON 错误 | const obj = {}; obj.self= obj; → 报错 |
三、转换规则示例
1. 基本类型
JSON.stringify("hello"); // '"hello"'
JSON.stringify(42); // '42'
JSON.stringify(true); // 'true'
JSON.stringify(null); // 'null'
2. 对象与数组
JSON.stringify({ a: 1, b: "2" }); // '{"a":1,"b":"2"}'
JSON.stringify([1, "2", null]); // '[1,"2",null]'
3. 特殊类型处理
// Date 对象
JSON.stringify(new Date()); // '"2023-10-01T00:00:00.000Z"'
// undefined 和函数
JSON.stringify({ a: undefined, b: function(){}, s: Symbol('s'),[Symbol('d')]: 's',f: ()=>1 }); // '{}'
// NaN/Infinity
JSON.stringify([NaN, Infinity]); // '[null,null]'
// Symbol
JSON.stringify(Symbol('key')); // undefined
4. **自定义 ****toJSON()**
const obj = {
name: "John",
toJSON() {
return { name: this.name.toUpperCase() };
}
};
JSON.stringify(obj); // '{"name":"JOHN"}'
四、控制转换行为
1. **replacer**
** **参数(函数或数组)
过滤或修改序列化结果:
// 过滤属性
JSON.stringify({a: 1, b: 2}, ['a']); // '{"a":1}'
// 自定义转换
JSON.stringify({a: 1, b: 2}, (key, value) => {
return key === 'a' ? undefined : value;
}); // '{"b":2}'
2. **space**
** **参数(美化输出)
添加缩进或前缀:
JSON.stringify({a: 1}, null, 2);
/*
{
"a": 1
}
*/
五、总结
- 可安全转换:基本类型、普通对象、数组、日期(通过
toISOString
)、实现toJSON()
的对象。 - 被忽略或转换异常:
undefined
、函数、Symbol
、特殊对象(如Map
)、循环引用。 - 使用建议:处理复杂对象时,可结合
replacer
函数或自定义toJSON()
方法控制输出。