JavaScript 对象如何转换为 JSON 字符串格式?
在 Web 开发中,JavaScript 与 JSON(JavaScript Object Notation)的数据交互极为常见,JSON 作为一种轻量级的数据交换格式,因其易读性和与 JavaScript 的天然兼容性,被广泛应用于前后端数据传输、配置文件存储等场景,将 JavaScript 对象或数组转换为 JSON 字符串,是前端开发中的基础操作之一,本文将详细介绍 JavaScript 中实现转换的核心方法、使用场景、注意事项及常见问题解决。
核心方法:JSON.stringify()
JavaScript 原生提供了 JSON 对象,该对象包含两个核心方法:JSON.parse()(用于将 JSON 字符串解析为 JavaScript 对象)和 JSON.stringify()(用于将 JavaScript 对象/数组转换为 JSON 字符串)。JSON.stringify() 是实现“JS 转 JSON 字符串”的核心工具。
基本语法
JSON.stringify() 的基本语法如下:
JSON.stringify(value[, replacer[, space]])
参数说明:
- value(必选):需要转换为 JSON 字符串的 JavaScript 对象、数组或基本数据类型(如字符串、数字、布尔值、
null),注意:undefined、函数、Symbol 会被忽略或转换为null。 - replacer(可选):用于控制转换过程的函数或数组。
- 若为函数:会对对象的每个属性递归调用该函数,返回值将作为该属性最终的 JSON 值(若返回
undefined,则该属性会被忽略)。 - 若为数组:只有数组中存在的键名才会被转换,其他属性会被忽略。
- 若为函数:会对对象的每个属性递归调用该函数,返回值将作为该属性最终的 JSON 值(若返回
- space(可选):用于格式化输出 JSON 字符串的缩进量。
- 若为数字(1-10):表示每级缩进的空格数,超过 10 会被自动限制为 10;
- 若为字符串(长度不超过 10):用该字符串作为缩进符(如
"\t"表示制表符); - 若省略或为
null/undefined,则输出无缩进的紧凑字符串。
基本使用示例
示例1:转换普通对象
const user = {
name: "张三",
age: 25,
isStudent: false,
hobbies: ["reading", "coding"],
address: {
city: "北京",
district: "海淀区"
}
};
const jsonString = JSON.stringify(user);
console.log(jsonString);
// 输出:{"name":"张三","age":25,"isStudent":false,"hobbies":["reading","coding"],"address":{"city":"北京","district":"海淀区"}}
示例2:转换数组
const numbers = [1, 2, { a: 10, b: 20 }];
const jsonFromArray = JSON.stringify(numbers);
console.log(jsonFromArray);
// 输出:[1,2,{"a":10,"b":20}]
示例3:格式化输出(使用 space 参数)
const formattedJson = JSON.stringify(user, null, 2); // 数字 2 表示每级缩进 2 个空格
console.log(formattedJson);
/* 输出:
{
"name": "张三",
"age": 25,
"isStudent": false,
"hobbies": [
"reading",
"coding"
],
"address": {
"city": "北京",
"district": "海淀区"
}
}
*/
进阶使用:replacer 参数的灵活控制
replacer 参数可以让我们自定义哪些属性需要被转换,以及转换后的值是什么,适用于敏感数据过滤或数据格式化场景。
使用函数作为 replacer
const sensitiveData = {
username: "admin",
password: "123456", // 敏感字段,需要过滤
token: "abc.xyx.zzz"
};
// 过滤掉 password 字段,并将 token 值脱敏
const filteredJson = JSON.stringify(sensitiveData, (key, value) => {
if (key === "password") {
return undefined; // 忽略该字段
}
if (key === "token") {
return value.substring(0, 3) + "***"; // 部分脱敏
}
return value;
});
console.log(filteredJson);
// 输出:{"username":"admin","token":"abc***"}
使用数组作为 replacer
仅转换数组中指定的属性名,其他属性会被忽略。
const userData = {
id: 1001,
name: "李四",
email: "lisi@example.com",
phone: "13800138000"
};
// 仅保留 name 和 email
const selectedJson = JSON.stringify(userData, ["name", "email"]);
console.log(selectedJson);
// 输出:{"name":"李四","email":"lisi@example.com"}
注意事项:JSON.stringify() 的行为边界
JSON.stringify() 并非能处理所有 JavaScript 数据类型,以下情况需要特别注意:
不支持的数据类型会被忽略或转为 null
undefined、函数、Symbol:直接被忽略(不包含在输出字符串中)。- 循环引用:会抛出
TypeError错误。
示例:忽略不支持的类型
const data = {
name: "王五",
age: function() { return 30; }, // 函数被忽略
hobby: undefined, // undefined 被忽略
symbolKey: Symbol("id") // Symbol 被忽略
};
console.log(JSON.stringify(data)); // 输出:{"name":"王五"}
示例:循环引用报错
const obj = { a: 1 };
obj.self = obj; // obj 引用了自身,形成循环
try {
JSON.stringify(obj);
} catch (error) {
console.error(error); // TypeError: Converting circular structure to JSON
}
原型链上的属性不会被转换
JSON.stringify() 仅转换对象自身的可枚举属性,不会包含原型链上的属性。
function Person(name) {
this.name = name;
}
Person.prototype.age = 20; // 原型属性
const person = new Person("赵六");
console.log(JSON.stringify(person)); // 输出:{"name":"赵六"}(不包含 age)
特殊对象的转换逻辑
部分内置对象(如 Date、RegExp、Map、Set)会被特殊处理:
Date对象:调用toISOString()转换为 ISO 格式的字符串(如"2023-10-01T00:00:00.000Z")。RegExp、Map、Set:会被转换为空对象 。
示例:
const specialData = {
date: new Date(),
regex: /\d+/,
map: new Map([["key", "value"]]),
set: new Set([1, 2, 3])
};
console.log(JSON.stringify(specialData));
// 输出:{"date":"2023-10-01T12:00:00.000Z","regex":{},"map":{},"set":{}}
替代方案与自定义转换
当 JSON.stringify() 无法满足需求时(如处理循环引用、自定义特殊对象格式),可以通过自定义函数实现转换。
处理循环引用(使用 WeakMap 缓存)
function stringifyWithCircular(obj) {
const cache = new WeakMap();
function _stringify(data) {
if (data === null || typeof data !== "object") {
return JSON.stringify(data);
}
// 检查循环引用
if (cache.has(data)) {
return "[Circular]";
}
cache.set(data, true);
if (Array.isArray(data)) {
const items = data.map(item => _stringify(item));
return `[${items.join(",")}]`;
} else {
const keys = Object.keys(data);
const entries = keys.map(key => {
const value = _stringify(data[key]);
return `"${key}":${value}`;
});
return `{${entries.join(",")}}`;
}
}
return _stringify(obj);
}
// 测试循环引用
const circularObj = { a: 1 };
circularObj.self = circularObj;
console.log(stringifyWithCircular(circularObj)); // 输出:{"a":1,"self":"[Circular]"}
自定义特殊对象的转换(如 Date 转为时间戳)
function customStringify(obj) {
return JSON.stringify(obj, (key, value) => {
if (value instanceof Date) {
return value.getTime(); // 将 Date 转为时间戳
}


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