JavaScript中如何将值转换为JSON格式
在JavaScript开发中,将数据转换为JSON(JavaScript Object Notation)格式是一项常见操作,JSON作为一种轻量级的数据交换格式,因其易读性和与JavaScript的天然兼容性,被广泛应用于前后端数据交互、配置存储等场景,本文将详细介绍JavaScript中将不同类型值转换为JSON的方法、注意事项及实际应用示例。
核心方法:JSON.stringify()
JavaScript原生提供了JSON.stringify()方法,这是将值转换为JSON格式字符串的主要工具,该方法能将JavaScript对象、数组、基本数据类型等转换为符合JSON标准的字符串,同时支持序列化过程中的格式化和过滤功能。
基本语法
JSON.stringify(value, replacer, space)
- value:必填,要转换的JavaScript值(对象、数组、基本类型等)。
- replacer:可选,用于控制序列化过程的函数或数组。
- 若为函数,则对每个属性调用该函数,返回值将被序列化(若返回
undefined,则该属性会被忽略); - 若为数组,则只序列化数组中指定的属性名。
- 若为函数,则对每个属性调用该函数,返回值将被序列化(若返回
- space:可选,格式化输出时的缩进字符串或数字,用于美化JSON字符串(便于阅读,但不影响数据结构)。
基本数据类型转换
JSON.stringify()对JavaScript基本数据类型的转换规则如下:
| 数据类型 | 转换结果示例 | 说明 |
|---|---|---|
| 对象(Object) | {"name":"Alice","age":25} |
对象的可枚举属性会被转换为JSON对象的键值对,方法、Symbol属性会被忽略。 |
| 数组(Array) | [1,"two",null,true] |
数组按索引顺序转换为JSON数组,undefined、函数、Symbol会被转为null。 |
| 字符串(String) | "Hello"(带双引号) |
字符串会被包裹在双引号中(JSON标准要求)。 |
| 数字(Number) | 123、-3.14 |
数字直接转换,Infinity和NaN会被转为null。 |
| 布尔值(Boolean) | true、false |
布尔值直接转换。 |
| null | null |
null直接转换。 |
| undefined | undefined |
不会被序列化(出现在对象属性中时会被忽略,数组中转为null)。 |
| 函数、Symbol | 被忽略或转为null |
对象中的方法、Symbol属性会被跳过;数组中的函数、Symbol转为null。 |
示例演示
(1)对象序列化
const user = {
name: "Bob",
age: 30,
isAdmin: true,
hobbies: ["reading", "coding"],
sayHi: function() { console.log("Hi"); }, // 方法会被忽略
[Symbol("id")]: 123 // Symbol属性会被忽略
};
const jsonString = JSON.stringify(user);
console.log(jsonString);
// 输出: {"name":"Bob","age":30,"isAdmin":true,"hobbies":["reading","coding"]}
(2)数组序列化
const mixedArray = [1, "two", undefined, null, true, function() {}];
console.log(JSON.stringify(mixedArray));
// 输出: [1,"two",null,null,true,null]
// undefined和函数被转为null
(3)基本类型序列化
console.log(JSON.stringify("Hello")); // "Hello"(带双引号)
console.log(JSON.stringify(123)); // 123
console.log(JSON.stringify(true)); // true
console.log(JSON.stringify(null)); // null
console.log(JSON.stringify(undefined)); // undefined(不会被序列化,输出undefined)
进阶用法:replacer参数
replacer参数可以灵活控制序列化结果,支持两种形式:函数和数组。
replacer为函数
对每个属性调用该函数,参数为(key, value),返回值作为该属性序列化后的结果,若返回undefined,则该属性会被忽略。
const user = {
name: "Charlie",
age: 25,
password: "123456", // 敏感信息,希望过滤掉
role: "admin"
};
// 过滤掉password属性,并将age值+10
const filteredJson = JSON.stringify(user, (key, value) => {
if (key === "password") {
return undefined; // 忽略password
}
if (key === "age") {
return value + 10; // 修改age值
}
return value; // 其他属性正常返回
});
console.log(filteredJson);
// 输出: {"name":"Charlie","age":35,"role":"admin"}
replacer为数组
只序列化数组中指定的属性名,其他属性会被忽略。
const product = {
id: 101,
name: "Laptop",
price: 999.99,
stock: 50,
category: "Electronics"
};
// 只序列化id、name、price
const selectedJson = JSON.stringify(product, ["id", "name", "price"]);
console.log(selectedJson);
// 输出: {"id":101,"name":"Laptop","price":999.99}
格式化输出:space参数
space参数用于美化JSON字符串,便于调试或展示,可以是:
- 数字(1-10):表示缩进空格数,例如
2表示每个层级缩进2个空格; - 字符串(长度不超过10):用作缩进字符(如
"\t"表示制表符)。
示例
const data = {
user: "David",
details: {
age: 28,
skills: ["JavaScript", "Python"]
}
};
// 使用数字缩进(2个空格)
const prettyJson1 = JSON.stringify(data, null, 2);
console.log(prettyJson1);
/* 输出:
{
"user": "David",
"details": {
"age": 28,
"skills": [
"JavaScript",
"Python"
]
}
}
*/
// 使用字符串缩进(制表符)
const prettyJson2 = JSON.stringify(data, null, "\t");
console.log(prettyJson2);
/* 输出:
{
"user": "David",
"details": {
"age": 28,
"skills": [
"JavaScript",
"Python"
]
}
}
*/
注意事项与常见问题
循环引用问题
如果对象中存在循环引用(例如对象的某个属性指向自身),JSON.stringify()会直接抛出错误。
const obj = {};
obj.self = obj; // 循环引用
console.log(JSON.stringify(obj)); // TypeError: Converting circular structure to JSON
解决方案:在序列化前手动处理循环引用,例如使用WeakMap标记已处理的对象,或自定义序列化逻辑过滤循环引用。
特殊对象的序列化
JavaScript中一些内置对象(如Date、Map、Set、RegExp等)的序列化结果可能不符合预期:
-
Date对象:会被转换为ISO格式的字符串(自动调用toISOString())。console.log(JSON.stringify(new Date())); // "2023-10-01T12:00:00.000Z"
-
Map/Set:默认会被转换为空对象(因为JSON不支持Map和Set)。console.log(JSON.stringify(new Map([["a", 1]]))); // "{}" -
RegExp对象:会被转换为空对象。console.log(JSON.stringify(/abc/)); // "{}"
解决方案:通过replacer函数手动处理这些对象,将其转换为可序列化的格式。
const data = {
date: new Date(),
map: new Map([["key", "value"]])
};
const customJson = JSON.stringify(data, (key, value) => {
if (value instanceof Date) {
return value.toISOString(); // Date转为ISO字符串
}
if (value instanceof Map) {
return Object.fromEntries(value); // Map转为普通对象
}
return value;
});
console.log(customJson);
// 输出: {"date":"2023-10-01T12:00:00.000Z","map":{"key":"value"}}
undefined的处理
- 对象属性中的
undefined:会被忽略(



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