← 返回博客

JavaScript JSON:解析和字符串化数据

JavaScript 中 JSON 的完整指南。学习 JSON.parse()、JSON.stringify()、错误处理和 Web 开发的高级技术。

Big JSON Team12 分钟阅读programming
B

Big JSON Team

Technical Writer

Expert in JSON data manipulation, API development, and web technologies. Passionate about creating tools that make developers' lives easier.

12 分钟阅读

# JavaScript JSON:解析和字符串化数据

JavaScript 通过 JSON 全局对象提供原生 JSON 支持,具有两个主要方法:JSON.parse()JSON.stringify()。本指南涵盖了在 Web 开发中使用 JSON 所需的一切。

JavaScript 中的 JSON

JSON 对象提供了在 JSON 格式和 JavaScript 值之间转换的方法。它是 ECMAScript 5 的一部分,在所有现代浏览器中都可用。

主要方法

  • JSON.parse():将 JSON 字符串解析为 JavaScript 对象
  • JSON.stringify():将 JavaScript 值转换为 JSON 字符串

JSON.parse() - 解析 JSON 字符串

将 JSON 字符串转换为 JavaScript 对象:

基本用法

const jsonString = '{"name": "张三", "age": 30, "city": "北京"}';

const obj = JSON.parse(jsonString);

console.log(obj.name); // "张三"

console.log(obj.age); // 30

console.log(obj.city); // "北京"

解析数组

const arrayString = '[1, 2, 3, 4, 5]';

const numbers = JSON.parse(arrayString);

console.log(numbers[0]); // 1

console.log(numbers.length); // 5

解析嵌套对象

const jsonString = '{

"user": {

"name": "李四",

"address": {

"city": "上海",

"district": "浦东"

}

}

}';

const data = JSON.parse(jsonString);

console.log(data.user.address.city); // "上海"

解析布尔值和 null

const jsonString = '{"active": true, "deleted": false, "value": null}';

const obj = JSON.parse(jsonString);

console.log(obj.active); // true

console.log(obj.deleted); // false

console.log(obj.value); // null

JSON.stringify() - 转换为 JSON

将 JavaScript 对象转换为 JSON 字符串:

基本用法

const user = {

name: "王五",

age: 25,

active: true,

city: "广州"

};

const json = JSON.stringify(user);

console.log(json);

// {"name":"王五","age":25,"active":true,"city":"广州"}

美化输出

使用第三个参数添加缩进:

const formatted = JSON.stringify(user, null, 2);

console.log(formatted);

// {

// "name": "王五",

// "age": 25,

// "active": true,

// "city": "广州"

// }

// 使用 4 空格缩进

const formatted4 = JSON.stringify(user, null, 4);

// 使用制表符

const formattedTab = JSON.stringify(user, null, '\t');

字符串化数组

const colors = ["红色", "绿色", "蓝色"];

const json = JSON.stringify(colors);

console.log(json); // ["红色","绿色","蓝色"]

字符串化嵌套对象

const company = {

name: "科技创新",

employees: [

{ name: "张三", role: "开发者" },

{ name: "李四", role: "设计师" }

],

active: true

};

const json = JSON.stringify(company, null, 2);

console.log(json);

替换器和复活器函数

替换器 - 过滤属性

使用替换器函数控制序列化:

const data = {

name: "张三",

password: "secret123",

age: 30,

email: "zhangsan@example.com"

};

// 过滤敏感数据

const json = JSON.stringify(data, (key, value) => {

if (key === "password") return undefined;

return value;

});

console.log(json);

// {"name":"张三","age":30,"email":"zhangsan@example.com"}

替换器数组

只包含指定的属性:

const user = {

name: "李四",

age: 28,

password: "secret",

email: "lisi@example.com"

};

const json = JSON.stringify(user, ["name", "email"]);

console.log(json);

// {"name":"李四","email":"lisi@example.com"}

复活器 - 转换值

使用复活器函数转换解析的值:

const jsonString = '{"date":"2026-01-15T00:00:00Z","count":"42"}';

const obj = JSON.parse(jsonString, (key, value) => {

// 将日期字符串转换为 Date 对象

if (key === "date") {

return new Date(value);

}

// 将数字字符串转换为数字

if (key === "count") {

return parseInt(value);

}

return value;

});

console.log(obj.date instanceof Date); // true

console.log(typeof obj.count); // "number"

高级复活器示例

const jsonString = '{

"created": "2026-01-15T10:30:00Z",

"modified": "2026-01-15T14:20:00Z",

"price": "99.99"

}';

const obj = JSON.parse(jsonString, (key, value) => {

// 自动转换所有日期字段

if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}T/.test(value)) {

return new Date(value);

}

// 转换价格

if (key === "price") {

return parseFloat(value);

}

return value;

});

console.log(obj);

错误处理

捕获解析错误

const invalidJson = '{"name": "张三", "age": 30,}';  // 尾随逗号

try {

const obj = JSON.parse(invalidJson);

} catch (error) {

console.error("JSON 解析错误:", error.message);

// JSON 解析错误:Unexpected token } in JSON at position 26

}

安全的 JSON 解析

创建一个安全的解析器函数:

function safeJSONParse(jsonString, fallback = null) {

try {

return JSON.parse(jsonString);

} catch (error) {

console.error("无法解析 JSON:", error.message);

return fallback;

}

}

// 使用

const result = safeJSONParse('invalid json', {});

console.log(result); // {}

验证 JSON

function isValidJSON(str) {

try {

JSON.parse(str);

return true;

} catch (e) {

return false;

}

}

console.log(isValidJSON('{"name":"张三"}')); // true

console.log(isValidJSON('{name: "张三"}')); // false(单引号)

console.log(isValidJSON('{"name":"张三",}')); // false(尾随逗号)

数据类型映射

JavaScript 到 JSON

| JavaScript 类型 | JSON 表示 |

|----------------|----------|

| Object | object |

| Array | array |

| String | string |

| Number | number |

| Boolean | true/false |

| null | null |

| undefined | 省略 |

| Function | 省略 |

| Symbol | 省略 |

| Date | 字符串(需要 toJSON) |

特殊值处理

const data = {

name: "张三",

age: 30,

active: true,

deleted: false,

value: null,

undefined: undefined, // 将被省略

fn: function() {}, // 将被省略

date: new Date() // 转换为 ISO 字符串

};

console.log(JSON.stringify(data));

// {"name":"张三","age":30,"active":true,"deleted":false,"value":null,"date":"2026-01-15T..."}

实际示例

示例 1:本地存储

// 保存到 localStorage

const user = {

name: "张三",

preferences: {

theme: "dark",

language: "zh"

}

};

localStorage.setItem('user', JSON.stringify(user));

// 从 localStorage 读取

const savedUser = JSON.parse(localStorage.getItem('user'));

console.log(savedUser.preferences.theme); // "dark"

示例 2:Fetch API

// 发送 JSON 数据

const postData = async () => {

const data = {

username: "zhangsan",

email: "zhangsan@example.com"

};

const response = await fetch('https://api.example.com/users', {

method: 'POST',

headers: {

'Content-Type': 'application/json'

},

body: JSON.stringify(data)

});

const result = await response.json(); // 自动解析 JSON

console.log(result);

};

示例 3:深度克隆

// 简单的深度克隆(有限制)

const original = {

name: "张三",

address: {

city: "北京",

district: "朝阳"

},

hobbies: ["阅读", "编程"]

};

const clone = JSON.parse(JSON.stringify(original));

// 修改克隆不会影响原始对象

clone.address.city = "上海";

console.log(original.address.city); // "北京"

console.log(clone.address.city); // "上海"

注意:这种方法有限制:
  • 丢失函数
  • 丢失 undefined 值
  • 日期转换为字符串
  • 不处理循环引用

示例 4:表单数据序列化

// 表单数据到 JSON

const form = document.querySelector('form');

const formData = new FormData(form);

const data = Object.fromEntries(formData);

const json = JSON.stringify(data);

// 发送到服务器

fetch('/api/submit', {

method: 'POST',

headers: { 'Content-Type': 'application/json' },

body: json

});

示例 5:配置管理

class ConfigManager {

constructor() {

this.config = this.load();

}

load() {

const saved = localStorage.getItem('app-config');

return saved ? JSON.parse(saved) : this.getDefaults();

}

save() {

localStorage.setItem('app-config', JSON.stringify(this.config));

}

get(key) {

return this.config[key];

}

set(key, value) {

this.config[key] = value;

this.save();

}

getDefaults() {

return {

theme: 'light',

language: 'zh',

notifications: true

};

}

}

// 使用

const config = new ConfigManager();

config.set('theme', 'dark');

console.log(config.get('theme')); // "dark"

性能优化

避免重复解析

// 不好:重复解析

for (let i = 0; i < 1000; i++) {

const obj = JSON.parse(jsonString);

process(obj);

}

// 好:解析一次

const obj = JSON.parse(jsonString);

for (let i = 0; i < 1000; i++) {

process(obj);

}

大对象处理

// 对于非常大的对象,考虑分块处理

function processLargeJSON(jsonString) {

try {

const data = JSON.parse(jsonString);

// 分块处理

const chunkSize = 100;

for (let i = 0; i < data.length; i += chunkSize) {

const chunk = data.slice(i, i + chunkSize);

processChunk(chunk);

}

} catch (error) {

console.error("处理失败:", error);

}

}

常见陷阱

1. 循环引用

const obj = { name: "张三" };

obj.self = obj; // 循环引用

try {

JSON.stringify(obj);

} catch (error) {

console.error(error); // TypeError: Converting circular structure to JSON

}

// 解决方案:使用替换器

const seen = new WeakSet();

const json = JSON.stringify(obj, (key, value) => {

if (typeof value === "object" && value !== null) {

if (seen.has(value)) {

return;

}

seen.add(value);

}

return value;

});

2. 日期处理

const data = {

name: "事件",

date: new Date("2026-01-15")

};

// Date 转换为 ISO 字符串

const json = JSON.stringify(data);

console.log(json);

// {"name":"事件","date":"2026-01-15T00:00:00.000Z"}

// 解析回来是字符串,不是 Date

const parsed = JSON.parse(json);

console.log(typeof parsed.date); // "string"

// 解决方案:使用复活器

const restored = JSON.parse(json, (key, value) => {

if (key === "date") return new Date(value);

return value;

});

console.log(restored.date instanceof Date); // true

3. NaN 和 Infinity

const data = {

nan: NaN,

infinity: Infinity,

negInfinity: -Infinity

};

console.log(JSON.stringify(data));

// {"nan":null,"infinity":null,"negInfinity":null}

4. undefined vs null

const data = {

value1: null,

value2: undefined

};

console.log(JSON.stringify(data));

// {"value1":null}

// value2 被省略

最佳实践

1. 始终处理错误

function parseJSON(str) {

try {

return JSON.parse(str);

} catch (error) {

console.error("JSON 解析失败:", error.message);

return null;

}

}

2. 验证 API 响应

async function fetchData(url) {

const response = await fetch(url);

if (!response.ok) {

throw new Error(HTTP 错误!状态:${response.status});

}

const data = await response.json();

// 验证数据结构

if (!data || typeof data !== 'object') {

throw new Error('无效的响应数据');

}

return data;

}

3. 使用 TypeScript 进行类型安全

interface User {

name: string;

age: number;

email: string;

}

function parseUser(jsonString: string): User | null {

try {

const data = JSON.parse(jsonString);

// 运行时验证

if (!data.name || !data.age || !data.email) {

throw new Error('缺少必需字段');

}

return data as User;

} catch (error) {

console.error('解析用户失败:', error);

return null;

}

}

4. 格式化用于调试

console.log('调试数据:', JSON.stringify(data, null, 2));

5. 压缩用于生产

// 开发

const devJSON = JSON.stringify(data, null, 2);

// 生产

const prodJSON = JSON.stringify(data);

浏览器兼容性

JSON 对象在所有现代浏览器中都支持:
  • ✅ Chrome 3+
  • ✅ Firefox 3.5+
  • ✅ Safari 4+
  • ✅ Edge(所有版本)
  • ✅ IE 8+

对于旧浏览器,可以使用 polyfill:

<script src="https://cdn.jsdelivr.net/npm/json3@3.3.3/lib/json3.min.js"></script>

结论

JavaScript 的原生 JSON 支持使得处理 JSON 数据变得简单高效。通过掌握 JSON.parse()JSON.stringify(),以及它们的高级功能,您可以:

  • ✅ 轻松解析和生成 JSON 数据
  • ✅ 处理复杂的数据结构
  • ✅ 实现自定义序列化和反序列化
  • ✅ 安全地处理错误
  • ✅ 优化性能

关键要点

  • 使用 JSON.parse() 将 JSON 字符串转换为对象
  • 使用 JSON.stringify() 将对象转换为 JSON
  • 始终用 try-catch 包装解析操作
  • 使用替换器过滤敏感数据
  • 使用复活器转换特殊类型
  • 注意循环引用和特殊值
  • 通过这些技术,您已准备好在 JavaScript 应用程序中自信地使用 JSON!

    Share:

    相关文章

    Read in English