← 返回目录

1. JSON 基础

JSON 就是前后端传数据的标准格式,本质是字符串,但长得像 JS 对象。

核心两个:
1. JSON.stringify(obj)——对象转字符串
2. JSON.parse(str)——字符串转对象

坑:JSON 键名必须双引号、不能有函数和 undefined、JSON 不是对象(是字符串)

但要注意:JSON 本质上是一段纯字符串,不是 JS 对象。它长得像 JS 对象,但它是"书面文字",JS 看不懂,得先用 JSON.parse 翻译成 JS 对象才能用。反过来,你要把数据传给后端,也得用 JSON.stringify 把 JS 对象翻译成 JSON 字符串。这一进一出,就是这节课要掌握的全部。

1.1 互动演示(自己动手解析和序列化)

输入 JSON 文本校验:
输入 JSON 点"解析",或点右边看 stringify 效果。

1.2 知识点讲解

1. JSON 到底是什么?为什么要用它?

打个比方:英语是全世界通用的沟通语言,法国人、日本人、中国人都用英语交流。JSON 就是编程世界里的"英语"——不管后端用什么语言写,前端用 JS 读,大家都用 JSON 来交换数据。

如果没有 JSON,Java 后端给你送一个它自己格式的数据,你的 JS 根本不认识,就像法国人给你递了一份法语菜单,你看不懂。有了 JSON,大家都用"普通话"传数据,谁都能解析。

// 类比:英语 = 全球人类通用语言
// JSON = 所有编程语言通用的"数据语言"
// 后端 Java/PHP/Python 和前端 JS 之间传数据,统一用 JSON
// 因为 JSON 是纯文本,谁都能读,不挑编程语言
// ★ 关键认知:JSON 本质是纯字符串,不是 JS 对象!
// 它只是"长得像" JS 对象,但它是一段文本。
// 就像一封写在纸上的信,纸是纸,字是字,
// 你得先"读信"(JSON.parse)才能知道信里写了什么。

如果你把 JSON 当成 JS 对象直接访问 .name,就会报错——因为它是字符串,字符串没有 .name 属性。因为 JSON 只是"长得像"对象的一段文字,必须先 JSON.parse 才变成真对象。

2. 两种标准 JSON 结构(日常就用这两种)

JSON 有两种最常用的"长相":一种是对象型(像字典,有键有值),一种是数组型(像清单,一排数据)。

// 1. 对象型 JSON(键值对)—— 描述"一个东西的各项属性"
// 像字典:"名字"是"张三","年龄"是18
// ← 这就是对象型:像字典,有键有值
{ "name": "张三", "age": 18, "gender": "男" }

// 2. 数组型 JSON(批量数据)—— 描述"一排东西"
// 像购物清单:苹果、香蕉、橙子
// ← 这就是数组型:像清单,一排排好的数据
["苹果", "香蕉", "橙子"]

// 数组里也能装对象(最常见!接口返回的列表数据基本都长这样)
// [ {"id":1,"name":"商品A"}, {"id":2,"name":"商品B"} ]

3. JSON 六条强制书写规范(考试必考,写错就报错)

JSON 有自己严格的"语法规矩",比 JS 严格多了。下面六条每一条都是新手常犯的错,记住:

// 规则1:JSON 本质是纯字符串,不属于 JS 独有语法
// (它只是刚好和 JS 对象长得像而已)

// 规则2:业务开发最常用对象型、数组型两种结构
// (标准语法上顶层也能写纯字符串、数字、布尔、null,但项目里基本不用)

// 规则3:所有键名必须用双引号包裹!
// "name" 正确
// 'name' 单引号,非法
// name 不加引号,非法

// 规则4:值允许写——字符串、数字、布尔(true/false)、null
// 值禁止写——function(函数)、undefined、NaN
// 因为 JSON 是纯数据,不能放代码

// 规则5:数组/对象末尾不能多一个逗号!
// {"a":1, "b":2} 正确
// {"a":1, "b":2,} 末尾多逗号,解析直接报错

// 规则6:JSON 文件后缀是 .json
// 文件里只能写纯 JSON 数据,
// 不能写 JS 代码、不能写注释(
// 这种在 .json 里是非法的!)

如果你写 {'name':'张三'}(用了单引号)JSON.parse 会直接报错——因为 JSON 规定键名必须双引号。如果你在末尾多写了个逗号 {"a":1,},也会报错——因为 JSON 不允许尾随逗号。这两条是新手 80% 报错的来源。

4. JSON.parse 和 JSON.stringify:一对互转方法

前面说了,JSON 是字符串,JS 对象是对象,两者之间要"翻译"。JS 自带了一对翻译机:

// ===== 翻译机一:JSON.stringify =====
// 作用:把 JS 对象 → JSON 字符串
// 什么时候用:要把数据存进 localStorage、要传给后端时

// 这是一个 JS 对象
let user = { name: "张三", age: 18 };

// 翻译:对象 → 字符串
let jsonStr = JSON.stringify(user);

// 打印:{"name":"张三","age":18}
console.log(jsonStr);

// ★ 注意:打印出来的是字符串,外面没有单引号包裹是因为
// console.log 自动去掉了外层引号

// ===== 翻译机二:JSON.parse =====
// 作用:把 JSON 字符串 → JS 对象
// 什么时候用:收到后端返回的数据、从 localStorage 读数据时

// 翻译:字符串 → 对象
let jsObj = JSON.parse(jsonStr);

// 打印:张三(现在能 .name 了!)
console.log(jsObj.name);

// ===== 单独写一段 JSON 字符串时,外面要套单引号 =====
// 因为双引号在 JS 里会提前结束字符串,所以外层用单引号

// 外层单引号,内层双引号
let str = '{"fruit":"苹果","price":9.9}';

// 解析成对象
let res = JSON.parse(str);

// 打印:苹果
console.log(res.fruit);

如果你把一段格式不对的 JSON 传给 JSON.parse,浏览器会直接抛 SyntaxError 红色报错,整个程序卡住。因为 parse 遇到不认识的格式会崩溃。所以实际项目里一定要用 try/catch 包起来,像下面这样:

try {
  // 尝试解析
  let obj = JSON.parse(可能有问题的字符串);
} catch (e) {
  // 出错就走这里,不崩溃
  console.log("JSON 格式不对:" + e.message);
}

5. JSON 的三大应用场景

// 场景1:前后端接口数据交互(最常用!)
// 后端返回的数据默认就是 JSON 格式
// 你 xhr.responseText 拿到的就是 JSON 字符串

// 场景2:本地存储 localStorage / sessionStorage
// 这俩只能存字符串!不能直接存对象
// 存之前 stringify,取出来之后 parse

// 存
localStorage.setItem("user", JSON.stringify(user));

// 取
let back = JSON.parse(localStorage.getItem("user"));

// 场景3:配置文件、项目静态数据
// 比如配置文件 config.json,只放纯数据

⑥ 实战:用在哪 / 常见坑 / 怎么解决

可能在什么地方用:

1. 后端接口返回数据时,你拿到的 xhr.responseText 就是 JSON 字符串,必须 JSON.parse 才能用
2. 往 localStorage 存对象/数组时,必须先 JSON.stringify,因为它只认字符串
3. 写 config.json 配置文件时,整个文件就是纯 JSON。

常见的问题:

1. 忘记 JSON.parse 就直接访问 data.name,结果打印出来是 undefined——因为它还是字符串
2. 拼 JSON 时键名写了单引号或没加引号,JSON.parse 直接报 SyntaxError
3. 末尾多写了逗号 {"a":1,},解析崩溃
4. 把 undefined 或函数当值塞进 JSON,JSON.stringify 会直接丢掉这个字段。

解决思路:

1. 报错时先看 Console 红字——SyntaxError: Unexpected token 就是 JSON 格式不对,回头查双引号和逗号
2. 解析前用 try/catch 包起来,出错不崩页面
3. 不确定时,把字符串贴到浏览器 Console 手动跑一次 JSON.parse(粘贴的内容),立刻知道哪错了。

一句话记住:JSON = 全编程语言通用的"数据普通话";本质是字符串;键名双引号、末尾不多逗号、值不能是 undefined/函数;JSON.stringify 对象转字符串、JSON.parse 字符串转对象;parse 要 try/catch

1.4 课后作业(融入本节)

练习一:JSON 格式校验新建 demo1.html,判断下面哪些是合法 JSON?在注释里写出判断依据。

// 1.  {"name": "张三", "age": 18} → 合法吗?为什么?
// 2.  {'name': '张三', 'age': 18} → 合法吗?为什么?
// 3.  {name: "张三", age: 18} → 合法吗?为什么?
// 4.  {"name": "张三", "age": 18,} → 合法吗?为什么?
// 5.  ["苹果", "香蕉", "橙子"] → 合法吗?为什么?
// ⑥ "hello" → 合法吗?为什么?
// ⑦ {"name": "张三", "age": undefined} → 合法吗?为什么?

// 再动手转一转:
// ⑧ 把 JS 对象 { name:"李四", age:25, hobbies:["读书","跑步"] }
// 用 JSON.stringify 转成字符串,打印结果
// ⑨ 把 JSON 字符串 '{"name":"王五","age":30,"address":{"city":"北京"}}'
// 用 JSON.parse 转成对象,打印 data.address.city

提示:对照上面六条规范一条一条查。2. 用了单引号、3. 没引号、4. 末尾多逗号、⑦值是 undefined——这几个是坑。

本页重点

API作用参数返回值代码示例
JSON.parse(str)把 JSON 字符串翻译成 JS 对象入参:JSON 字符串返回:JS 对象;格式错会抛错let obj = JSON.parse('{"name":"张三"}');
JSON.stringify(obj)把 JS 对象打包成 JSON 字符串入参:JS 对象返回:JSON 字符串let str = JSON.stringify(obj);
localStorage.setItem(k,v)把数据存到浏览器本地入参:键名、字符串值返回:无localStorage.setItem("token", "abc123");
localStorage.getItem(k)从浏览器本地取数据入参:键名返回:字符串;没有就 nulllet t = localStorage.getItem("token");