JSON 数据格式

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它是前端与后端通信的”通用语言”——几乎所有的 Web API 都使用 JSON 传输数据。

JSON 语法

JSON 的语法是 JavaScript 对象字面量的一个子集,但有严格的规则:

json
{
  "name": "张三",
  "age": 25,
  "isAdmin": false,
  "hobbies": ["编程", "阅读"],
  "address": {
    "city": "上海",
    "district": "浦东"
  }
}
规则JSONJavaScript 对象
键名必须用双引号可不加引号
字符串必须用双引号单引号或双引号
注释不允许允许
尾随逗号不允许允许
数据类型仅 string/number/boolean/null/array/object还包括 undefined/function/symbol 等
json
// ❌ 无效 JSON
{
  name: "张三",           // 键名未加引号
  'age': 25,             // 用单引号
  // 这是一条注释         // JSON 不支持注释
  "city": "上海",        // 尾随逗号
}
json
// ✅ 有效 JSON
{
  "name": "张三",
  "age": 25,
  "city": "上海"
}

JSON.stringify() — 对象 → JSON 字符串

将 JavaScript 对象转为 JSON 字符串:

javascript
const user = {
  name: '张三',
  age: 25,
  hobbies: ['编程', '阅读'],
};

const json = JSON.stringify(user);
console.log(json);
// {"name":"张三","age":25,"hobbies":["编程","阅读"]}

格式美化输出(缩进 2 空格):

javascript
const formatted = JSON.stringify(user, null, 2);
console.log(formatted);
/*
{
  "name": "张三",
  "age": 25,
  "hobbies": [
    "编程",
    "阅读"
  ]
}
*/

JSON.stringify 会自动忽略 undefined、函数和 Symbol 类型的属性。带有循环引用的对象会导致 JSON.stringify 报错——这在你要序列化 DOM 节点时经常遇到。

JSON.parse() — JSON 字符串 → 对象

将 JSON 字符串还原为 JavaScript 对象:

javascript
const jsonStr = '{"name":"张三","age":25}';
const user = JSON.parse(jsonStr);

console.log(user.name); // "张三"
console.log(user.age);  // 25

如果字符串不是合法 JSON,JSON.parse 会抛错:

javascript
try {
  JSON.parse('这不是 JSON');
} catch (error) {
  console.log('解析失败:', error.message);
}

深拷贝:JSON 的副产品

利用 JSON 的序列化/反序列化可以实现简单的深拷贝:

javascript
const original = { name: '张三', info: { age: 25 } };
const copy = JSON.parse(JSON.stringify(original));

copy.info.age = 30;
console.log(original.info.age); // 25(原对象不受影响)

JSON 深拷贝会丢失函数、undefined、Symbol 和 Date 等类型——函数和 Symbol 被忽略,Date 会变成字符串。对于包含这些类型的对象,使用 structuredClone() 替代。

fetch() + JSON — 完整的请求流程

javascript
async function loadUser(userId) {
  try {
    const response = await fetch(`/api/users/${userId}`);

    if (!response.ok) {
      console.error('请求失败:', response.status);
      return null;
    }

    const data = await response.json(); // 解析 JSON 响应
    return data;
  } catch (error) {
    console.error('网络错误:', error.message);
    return null;
  }
}

const user = await loadUser(1);
if (user) {
  console.log(user.name);
}

发送 JSON 数据

javascript
async function saveUser(user) {
  const response = await fetch('/api/users', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(user), // 对象 → JSON 字符串
  });
  return response.json();
}

错误处理

fetch() 只在网络错误(断网、DNS 解析失败)时 reject,HTTP 错误状态(404、500)不会导致 reject。需要手动检查 response.okresponse.status