JSON 是什么?和 JavaScript 对象的 5 个区别
一句话结论:JSON 是一种纯文本的数据交换格式,语法借自 JavaScript 对象,但它和 JS 对象不是一回事——最明显的区别是 JSON 的键必须用双引号,而且不能有注释、函数和尾随逗号。
为什么要有 JSON
在 JSON 出现之前,程序之间交换数据常用 XML。XML 表达力强,但标签多、体积大、解析慢。2001 年 Douglas Crockford 提出 JSON,只保留最必要的结构:
{
"name": "张三",
"age": 28,
"tags": ["前端", "后端"],
"address": { "city": "杭州" }
}
它只有两种复合结构:对象(花括号)和数组(方括号),值只能是字符串、数字、布尔、null、对象或数组。正因为简单,几乎所有语言都能在几十行代码内实现解析器,JSON 也就成了事实上的通用格式。
和 JavaScript 对象的 5 个区别
| # | 区别 | JSON | JavaScript 对象 |
|---|---|---|---|
| 1 | 键名 | 必须是双引号字符串 | 可省略引号,也可用标识符 |
| 2 | 注释 | 不允许 | 允许 |
| 3 | 尾随逗号 | 不允许 | 允许(ES5+ 对象字面量) |
| 4 | 值类型 | 不能是函数、undefined、NaN、Infinity | 都可以 |
| 5 | 本质 | 一段文本 | 内存里的对象实例 |
最容易踩的是第 1 条和第 3 条。下面两种写法在 JavaScript 里完全合法,但放进 JSON 就会报错:
// 这是 JS 对象,不是 JSON
const obj = {
name: '张三', // 键没有引号
age: 28, // 允许注释
}
怎么判断一段文本是不是合法 JSON
三个检查点,按出错频率排序:
- 所有键都有双引号吗(单引号也不行)
- 最后一个元素后面有没有多余逗号
- 有没有注释或不可见字符(从网页复制时常带 BOM)
浏览器自带的 JSON.parse() 是最严格的裁判——只要有一处不合规就直接抛错,错误信息里会指出位置。
JSON 和 JS 对象怎么互转
const text = JSON.stringify({ name: '张三' }) // 对象 → JSON 文本
const obj = JSON.parse(text) // JSON 文本 → 对象
JSON.stringify 会丢掉函数和 undefined 字段,JSON.parse 遇到不合法的文本会抛 SyntaxError。这两个行为都是规范要求的,不是 bug。
常见坑
- 把 JS 对象字面量当 JSON 用:能跑,但发给后端就解析失败
- 用 JSON.stringify 处理大对象:循环引用会直接抛错
- 从接口拿到的不是 JSON:404 页面返回 HTML 时,
JSON.parse报的是「unexpected token <」,具体排查见《JSON.parse: unexpected token 的 5 种原因》
常见问题
JSON 和 JavaScript 对象能直接互转吗?
可以,用 JSON.stringify 转成文本、JSON.parse 转回对象,但函数、undefined 和循环引用在转换时会丢失或报错。
JSON 的键可以不加双引号吗?
不行。JSON 规范要求键必须是双引号字符串,单引号或无引号都会解析失败。
为什么我的 JSON 加了注释就报错?
JSON 标准不支持注释。需要注释的话可以用 JSON5 或 JSONC 格式,但发给程序前要转换回标准 JSON。