JavaScript JSON.stringify()(超详细)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新开坑项目:《Spring AI 项目实战》 正在持续爆肝中,基于 Spring AI + Spring Boot 3.x + JDK 21..., 点击查看 ;
- 《从零手撸:仿小红书(微服务架构)》 已完结,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
在现代 Web 开发中,数据的序列化与传输是核心功能之一。JavaScript JSON.stringify() 方法作为 JavaScript 原生提供的工具,能够将 JavaScript 对象转化为 JSON 格式的字符串,这一过程在前后端交互、数据存储及 API 调用等场景中极为常见。无论是将用户输入的数据发送到服务器,还是将复杂对象保存到 localStorage
,JSON.stringify()
都是开发者不可或缺的工具。本文将从基础概念、核心用法到高级技巧,系统性地解析这一方法,并通过实际案例帮助读者掌握其应用场景与注意事项。
一、JSON 的基本概念与作用
1.1 什么是 JSON?
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它以文本形式存储和传输数据,具有以下特点:
- 结构清晰:通过键值对(Key-Value)组织数据,易于阅读和解析。
- 跨平台兼容:几乎所有现代编程语言(如 Python、Java、PHP 等)都支持 JSON 格式。
- 高效传输:相比 XML 等格式,JSON 的体积更小,解析速度更快。
1.2 JSON 与 JavaScript 的关系
JSON 的语法与 JavaScript 对象字面量(Object Literal)高度相似,例如:
// JavaScript 对象
const user = {
name: "Alice",
age: 25,
isStudent: true
};
// JSON 字符串
"{\"name\": \"Alice\", \"age\": 25, \"isStudent\": true}"
但 JSON 是一种独立的数据格式,它不依赖于任何编程语言。而 JSON.stringify()
的核心作用,正是将 JavaScript 对象转换为符合 JSON 标准的字符串。
二、JSON.stringify()
的基础用法
2.1 基本语法与参数
JSON.stringify()
的语法如下:
JSON.stringify(value, replacer?, space?)
value
:必需参数,需要转换为 JSON 字符串的 JavaScript 值(通常是对象或数组)。replacer
:可选参数,用于筛选或转换数据。可以是一个函数或数组。space
:可选参数,控制缩进和空格,用于美化输出格式。
2.2 简单对象的序列化
案例 1:将对象转换为 JSON 字符串
const person = {
firstName: "Bob",
lastName: "Smith",
hobbies: ["reading", "coding"],
isDeveloper: true
};
const jsonString = JSON.stringify(person);
console.log(jsonString);
// 输出:
// {"firstName":"Bob","lastName":"Smith","hobbies":["reading","coding"],"isDeveloper":true}
通过 JSON.stringify()
,对象中的键值对被转换为 JSON 格式,字符串中的键和字符串值均用双引号包裹,且自动处理了特殊字符(如换行符、引号等)。
三、深入理解 JSON.stringify()
的参数
3.1 replacer
参数:数据筛选与转换
3.1.1 使用函数过滤数据
通过 replacer
函数,可以自定义序列化逻辑,例如忽略某些属性或修改值:
const data = {
username: "john_doe",
password: "secret", // 敏感信息需排除
email: "john@example.com"
};
const filteredJSON = JSON.stringify(data, (key, value) => {
if (key === "password") return undefined; // 排除 password 属性
return value;
});
console.log(filteredJSON);
// 输出:{"username":"john_doe","email":"john@example.com"}
3.1.2 使用数组指定保留字段
若只需保留特定字段,可将 replacer
设置为字段名的数组:
const filteredJSONArray = JSON.stringify(data, ["username", "email"]);
// 输出:{"username":"john_doe","email":"john@example.com"}
3.2 space
参数:美化输出格式
通过 space
参数,可以控制 JSON 字符串的缩进和空格,提升可读性:
const prettyJSON = JSON.stringify(person, null, 2);
console.log(prettyJSON);
/* 输出:
{
"firstName": "Bob",
"lastName": "Smith",
"hobbies": [
"reading",
"coding"
],
"isDeveloper": true
}
*/
space
可接受数字(表示缩进空格数)或字符串(如 " "
或 "\t"
)。
四、常见问题与解决方案
4.1 不可序列化的数据类型
JSON.stringify()
会自动忽略以下数据类型,并在最终字符串中将其转换为 null
:
- 函数
undefined
Symbol
(ES6 引入的原始数据类型)
案例 2:包含不可序列化类型的对象
const invalidData = {
func: () => "Hello",
undef: undefined,
symbol: Symbol("id")
};
console.log(JSON.stringify(invalidData));
// 输出:{"func":null,"undef":null,"symbol":null}
解决方案:
若需保留函数或符号类型,需通过 replacer
函数手动处理,例如将函数转换为字符串:
const funcToString = JSON.stringify(invalidData, (key, value) => {
if (typeof value === "function") return value.toString();
return value;
});
// 输出包含函数的字符串表示
4.2 处理循环引用
当对象存在循环引用时,JSON.stringify()
会抛出错误:
const obj = { name: "Alice" };
obj.self = obj; // 创建循环引用
JSON.stringify(obj); // 抛出 TypeError: Converting circular structure to JSON
解决方案:
可通过 replacer
函数检测并替换循环引用:
const circularSafeStringify = (obj) => {
const cache = new WeakSet();
return JSON.stringify(obj, (key, value) => {
if (typeof value === "object" && value !== null) {
if (cache.has(value)) return "[Circular Reference]";
cache.add(value);
}
return value;
});
};
五、实际应用场景与最佳实践
5.1 发送数据到服务器
在与 RESTful API 交互时,常需将 JavaScript 对象转换为 JSON 字符串作为请求体:
fetch("/api/user", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ username: "alice", score: 95 })
});
5.2 本地存储与持久化
通过 localStorage
保存用户偏好设置时:
// 保存数据
localStorage.setItem("themeSettings", JSON.stringify({ theme: "dark", fontSize: 14 }));
// 读取数据
const settings = JSON.parse(localStorage.getItem("themeSettings"));
5.3 调试与日志记录
将复杂对象转换为字符串便于日志输出或调试:
console.log("Current state:", JSON.stringify(state, null, 2));
六、与其他方法的对比与扩展
6.1 JSON.parse()
的互补作用
JSON.parse()
是 JSON.stringify()
的逆过程,用于将 JSON 字符串解析为 JavaScript 对象:
const jsonStr = '{"name":"Bob","age":30}';
const parsedObj = JSON.parse(jsonStr);
console.log(parsedObj.name); // 输出:Bob
6.2 第三方库的替代方案
对于复杂场景(如处理循环引用或序列化 Symbol
),可借助第三方库如 flatted
或 json-stable-stringify
:
import flatted from "flatted";
const circularObj = { a: 1 };
circularObj.b = circularObj;
const safeStr = flatted.stringify(circularObj); // 输出:{"a":1,"b":{},"__ref__":0}
结论
JavaScript JSON.stringify() 是开发者工具箱中的核心方法,其简洁性与强大功能使其成为数据序列化的首选方案。通过本文的讲解,读者应能掌握以下要点:
- 基础用法:对象到 JSON 字符串的转换,参数
replacer
和space
的灵活应用。 - 问题处理:如何应对不可序列化类型、循环引用等常见挑战。
- 实际价值:在 API 调用、本地存储等场景中的关键作用。
建议读者通过编写小项目(如简易待办事项应用或数据可视化工具)实践 JSON.stringify()
,以加深理解。随着技术栈的扩展,结合 JSON.parse()
及第三方库,开发者能够应对更复杂的序列化需求,进一步提升数据交互的效率与安全性。