正在加载...

JavaScript 中的 JSON

上一页只是在改调用的方式,this 跟着那次调用走。这一页把那件事放下。商品还在内存里,名字和价格都在对象身上。要把同样的事实交给文件、另一个程序或后面的页面,就需要一份格式固定的文本。这份文本叫 JSON。

活着的对象不是这张便条

脚本还在跑的时候,字面量就在原地,也可以挂上方法;this 仍然由调用方式决定,和上一课一样。JSON 只是一个字符串:没有方法,也不会自己挑选 this。

这段文本允许装什么

📊 活对象与 JSON 文本

部分 对象字面量 JSON 文本
键的引号 可有可无 必须双引号
字符串引号 单引号或双引号 只能双引号
末尾逗号 允许 禁止
函数 可以当方法 stringify 会丢掉;写进文本里则不合法
undefined 字段 真实的值 stringify 走过对象时会省略

别把字面量的习惯带进这段文本。每个键、每段字符串都要双引号。行尾多一个逗号、文本里的注释、光秃的函数,都不是合格的 JSON。表里写着哪种习惯会被悄悄丢掉,哪种 parse 根本不收。

stringify 写下便条

javascript
let product = {
name: "Mug",
price: 12
};
console.log(JSON.stringify(product));

stringify 写下便条

JSON.stringify 走过普通字段,交回一个字符串;控制台显示 {"name":"Mug","price":12},而 product 本身不动。名字仍然从活对象上读,得到 Mug。字符串是另一份值,可以存起来,也可以送出去。

parse 还原出一个值

javascript
let text = '{"name":"Mug","price":12}';
let product = JSON.parse(text);
console.log(product.name);

parse 从便条还原出一个值

text 仍然是字符串,引号和花括号都在。JSON.parse 用这段文本造出一个新对象。之后 product.name 等于 Mug。这里没有调用方法,也没有 this 的事。

便条里的一份列表

javascript
let text = '{"name":"Mug","tags":["ceramic","gift"]}';
let product = JSON.parse(text);
console.log(product.tags[0]);

列表可以待在便条里面

JSON 文本可以装数组;parse 之后,product.tags 是真正的数组,第一格是 ceramic。数组作为单独的题目留到下一课,这里它只是文本里的货物。

便条留下行为

javascript
let product = {
name: "Mug",
price: undefined,
tag() {
return this.name;
}
};
console.log(JSON.stringify(product));

便条留数据,不留行为

price 当时是 undefined。tag 是一个函数。两样都从文本里消失。印出来的只有 {"name":"Mug"}。行为留在活对象上,进不了便条。

马虎的引号读不了

javascript
let text = "{name:'Mug'}";
try {
JSON.parse(text);
console.log("ok");
} catch (err) {
console.log("bad text");
}

马虎的便条无法解析

单引号和没加引号的键,在字面量里合法,在 JSON 里不合法;所以 JSON.parse 会抛错,catch 打出 bad text,免得这个演示把页面弄停。把键和字符串都改成双引号。这还不是后面的错误课,只是让你看见坏掉的 JSON 会拦住 parse。

方向清楚,工具就清楚

从内存到文本,用 stringify;从文本回到值,用 parse。过后如果商品上还需要函数,就在 parse 之后再补上,因为便条没把函数带来。this 仍然看调用方式,不看 JSON,下一课是数组:脚本里的活列表,不是又一条 JSON 规则。

把便条里的一个字段放到页面上

用 parse 读一小段商品字符串。把名字写进段落。不要在脚本里用花括号现造对象。

页面演示 — 便条里的名字

html
<!DOCTYPE html>
<html>
<head>
<title>json — page</title>
</head>
<body>
<p id="line">…</p>
<script>
let text = '{"name":"Mug","price":12}';
let product = JSON.parse(text);
let box = document.getElementById("line");
box.textContent = product.name;
</script>
</body>
</html>

段落显示 Mug,因为脚本没有造字面量,只解析了文本。改掉字符串里的名字再刷新,这一行会跟着变。

练习步骤

  1. 对杯子做 stringify,读出带引号的文本;再对同样的形状做 parse,看到 Mug。
  2. 解析带 tags 的便条,读出 ceramic。
  3. 对带方法且价格为 undefined 的对象做 stringify,让文本里只剩 name,再把没加引号的键放进 try / catch,直到出现 bad text。
  4. 在 HTML 演示里只改字符串中的名字,刷新,再读段落。

常见失手

  • 把 JSON 文本当成对象字面量,并把单引号或裸键交给 parse
  • 指望方法或 undefined 能熬过 stringify
  • 想要文本时却调用了 parse,文本已经在手时却调用了 stringify;还在字符串本身上读名字,而不是在 parse 交回的值上读
  • 把下一页也当成 JSON,其实数组是一份活的列表

收束

  • JSON 是描述数据的文本,stringify 把普通对象变成这段文本
  • parse 把文本变回一个值
  • 键和字符串要用双引号;多写逗号或用单引号会让 parse 失败
  • 方法和 undefined 字段会从文本里去掉
  • 解析出来的字段可以填页面上的一行,下一课是数组,脚本里的活列表

🧠 测试您的知识

准备开始

测试您的知识

通过这个互动测验挑战自己,看看你对这个主题的理解程度如何

❓
8
问题
🎯
70%
及格要求
♾️
∞
时间
🔄
∞
尝试次数

📝 说明

  • 仔细阅读每个问题
  • 为每个问题选择最佳答案
  • 您可以随时重新参加测验
  • 您的进度将显示在顶部