JavaScript 中优雅地“打出”JSON:从基础到实践
在 JavaScript 开发中,“打出 JSON” 通常指的是将 JavaScript 对象或值转换为 JSON 格式的字符串,这个过程在数据传输(如与服务器 API 交互)、数据存储或日志记录等场景中非常常见,JavaScript 提供了内置的方法来轻松实现这一功能,同时也处理了一些复杂情况,本文将详细介绍如何在 JavaScript 中“打出”JSON,包括基础用法、高级选项以及常见问题的解决方案。
核心方法:JSON.stringify()
要将 JavaScript 值转换为 JSON 字符串,我们主要使用 JSON 全局对象的 stringify() 方法。
基本语法
JSON.stringify() 方法的基本语法如下:
JSON.stringify(value, replacer, space)
- value: 必需参数,要转换为 JSON 字符串的 JavaScript 值,通常是对象或数组。
- replacer: 可选参数,可以是一个函数或一个数组,用于控制哪些属性被转换以及如何转换。
- space: 可选参数,一个字符串或数字,用于美化输出 JSON 字符串,增加缩进和换行,使其更易读。
简单示例:将对象转换为 JSON 字符串
假设我们有一个 JavaScript 对象:
const user = {
name: "张三",
age: 30,
isAdmin: true,
hobbies: ["阅读", "游泳", "编程"],
address: {
city: "北京",
district: "朝阳区"
}
};
使用 JSON.stringify() 将其转换为 JSON 字符串:
const jsonString = JSON.stringify(user); console.log(jsonString);
输出结果:
{"name":"张三","age":30,"isAdmin":true,"hobbies":["阅读","游泳","编程"],"address":{"city":"北京","district":"朝阳区"}}
可以看到,JavaScript 对象被成功转换为了一个 JSON 格式的字符串,注意,JSON 格式对字符串的键和值都使用双引号。
美化输出:使用 space 参数
默认情况下,JSON.stringify() 输出的 JSON 字符串是压缩在一行的,不利于阅读,我们可以使用 space 参数来格式化输出。
使用数字作为 space
数字表示缩进的空格数,通常使用 2 或 4。
const prettyJsonString = JSON.stringify(user, null, 2); console.log(prettyJsonString);
输出结果:
{
"name": "张三",
"age": 30,
"isAdmin": true,
"hobbies": [
"阅读",
"游泳",
"编程"
],
"address": {
"city": "北京",
"district": "朝阳区"
}
}
使用字符串作为 space
字符串将用作缩进,通常使用制表符 \t 或特定的字符串。
const prettyJsonStringWithTab = JSON.stringify(user, null, '\t'); console.log(prettyJsonStringWithTab);
输出结果:
{
"name": "张三",
"age": 30,
"isAdmin": true,
"hobbies": [
"阅读",
"游泳",
"编程"
],
"address": {
"city": "北京",
"district": "朝阳区"
}
}
自定义转换:使用 replacer 参数
replacer 参数提供了更精细的控制,可以过滤掉不需要的属性,或者对属性值进行修改。
使用数组作为 replacer(过滤属性)
如果只希望转换对象中的特定属性,可以将这些属性的名称作为数组传递给 replacer。
const nameAndAgeJson = JSON.stringify(user, ['name', 'age'], 2); console.log(nameAndAgeJson);
输出结果:
{
"name": "张三",
"age": 30
}
只有 name 和 age 属性被包含在输出的 JSON 字符串中。
使用函数作为 replacer(修改/过滤属性)
replacer 是一个函数,它会对对象本身和每个属性值调用一次,函数的返回值将被用作 JSON 字符串中的值,如果返回 undefined,则该属性将被排除。
- 第一个参数
key是当前属性的键。 - 第二个参数
value是当前属性的值。
示例1:过滤掉值为 null 或 undefined 的属性
const dataWithNull = {
a: 1,
b: null,
c: 'hello',
d: undefined,
e: true
};
const filteredJson = JSON.stringify(dataWithNull, (key, value) => {
if (value === null || value === undefined) {
return undefined; // 过滤掉 null 和 undefined
}
return value;
}, 2);
console.log(filteredJson);
输出结果:
{
"a": 1,
"c": "hello",
"e": true
}
示例2:修改特定属性的值
const modifiedJson = JSON.stringify(user, (key, value) => {
if (key === 'age') {
return value + 1; // 年龄加1
}
if (key === 'isAdmin' && !value) {
return undefined; // 如果不是管理员,则过滤掉该属性
}
return value;
}, 2);
console.log(modifiedJson);
输出结果(假设张三是管理员):
{
"name": "张三",
"age": 31,
"isAdmin": true,
"hobbies": [
"阅读",
"游泳",
"编程"
],
"address": {
"city": "北京",
"district": "朝阳区"
}
}
注意事项与常见问题
循环引用
如果对象中存在循环引用(即对象的某个属性间接或直接指向了对象本身),JSON.stringify() 会抛出 TypeError。
const obj = {};
obj.self = obj; // 循环引用
try {
JSON.stringify(obj);
} catch (error) {
console.error("错误:", error.message); // 错误: TypeError: Converting circular structure to JSON...
}
解决方案: 在使用 stringify 之前,需要手动处理循环引用,或者使用库来帮助处理。
特殊类型的处理
- 函数: 对象中的函数属性会被忽略(转换为
undefined)。 - Symbol: 对象中的 Symbol 属性会被忽略。
- undefined: 对象中的
undefined属性会被忽略。 - Date 对象: 会被转换为 ISO 格式的日期字符串(
"2023-10-27T10:00:00.000Z")。 - RegExp 对象: 会被转换为空对象 。
- Map, Set, WeakMap, WeakSet: 这些对象会被忽略。
示例:
const specialData = {
func: function() { console.log('hello'); },
undef: undefined,
sym: Symbol('id'),
date: new Date(),
regex: /test/g,
map: new Map([['key', 'value']])
};
console.log(JSON.stringify(specialData, null, 2));
输出结果:
{
"date": "2023-10-27T10:00:00.000Z",
"regex": {}
}
可以看到,函数、undefined、Symbol、Map 都被忽略了,Date 和 RegExp 被转换成了它们各自的字符串表示。
在 JavaScript 中“打出”JSON,核心就是 JSON.stringify() 方法,通过其三个参数:
- value: 明确你要转换的目标。
- replacer: 灵活控制属性的选择和转换,适用于数据过滤和定制化场景。
- space: 方便地美化输出,便于调试和日志查看。
也要注意其对于特殊类型和循环引用的处理方式,避免在开发过程中遇到意外错误,熟练运用 JSON.stringify(),将使你在处理数据序列化时更加得心应手。



还没有评论,来说两句吧...