JavaScript 中的 JSON
上一页只是在改调用的方式,this 跟着那次调用走。这一页把那件事放下。商品还在内存里,名字和价格都在对象身上。要把同样的事实交给文件、另一个程序或后面的页面,就需要一份格式固定的文本。这份文本叫 JSON。
活着的对象不是这张便条
脚本还在跑的时候,字面量就在原地,也可以挂上方法;this 仍然由调用方式决定,和上一课一样。JSON 只是一个字符串:没有方法,也不会自己挑选 this。
这段文本允许装什么
📊 活对象与 JSON 文本
| 部分 | 对象字面量 | JSON 文本 |
|---|---|---|
| 键的引号 | 可有可无 | 必须双引号 |
| 字符串引号 | 单引号或双引号 | 只能双引号 |
| 末尾逗号 | 允许 | 禁止 |
| 函数 | 可以当方法 | stringify 会丢掉;写进文本里则不合法 |
| undefined 字段 | 真实的值 | stringify 走过对象时会省略 |
别把字面量的习惯带进这段文本。每个键、每段字符串都要双引号。行尾多一个逗号、文本里的注释、光秃的函数,都不是合格的 JSON。表里写着哪种习惯会被悄悄丢掉,哪种 parse 根本不收。
let product = {
name: "Mug",
price: 12
};
console.log(JSON.stringify(product));
stringify 写下便条
JSON.stringify 走过普通字段,交回一个字符串;控制台显示 {"name":"Mug","price":12},而 product 本身不动。名字仍然从活对象上读,得到 Mug。字符串是另一份值,可以存起来,也可以送出去。
let text = '{"name":"Mug","price":12}';
let product = JSON.parse(text);
console.log(product.name);
parse 从便条还原出一个值
text 仍然是字符串,引号和花括号都在。JSON.parse 用这段文本造出一个新对象。之后 product.name 等于 Mug。这里没有调用方法,也没有 this 的事。
let text = '{"name":"Mug","tags":["ceramic","gift"]}';
let product = JSON.parse(text);
console.log(product.tags[0]);
列表可以待在便条里面
JSON 文本可以装数组;parse 之后,product.tags 是真正的数组,第一格是 ceramic。数组作为单独的题目留到下一课,这里它只是文本里的货物。
let product = {
name: "Mug",
price: undefined,
tag() {
return this.name;
}
};
console.log(JSON.stringify(product));
便条留数据,不留行为
price 当时是 undefined。tag 是一个函数。两样都从文本里消失。印出来的只有 {"name":"Mug"}。行为留在活对象上,进不了便条。
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 读一小段商品字符串。把名字写进段落。不要在脚本里用花括号现造对象。
<!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,因为脚本没有造字面量,只解析了文本。改掉字符串里的名字再刷新,这一行会跟着变。
练习步骤
- 对杯子做 stringify,读出带引号的文本;再对同样的形状做 parse,看到
Mug。 - 解析带
tags的便条,读出ceramic。 - 对带方法且价格为
undefined的对象做 stringify,让文本里只剩name,再把没加引号的键放进try/catch,直到出现bad text。 - 在 HTML 演示里只改字符串中的名字,刷新,再读段落。
常见失手
- 把 JSON 文本当成对象字面量,并把单引号或裸键交给
parse - 指望方法或
undefined能熬过stringify - 想要文本时却调用了
parse,文本已经在手时却调用了stringify;还在字符串本身上读名字,而不是在parse交回的值上读 - 把下一页也当成 JSON,其实数组是一份活的列表
收束
- JSON 是描述数据的文本,
stringify把普通对象变成这段文本 parse把文本变回一个值- 键和字符串要用双引号;多写逗号或用单引号会让
parse失败 - 方法和
undefined字段会从文本里去掉 - 解析出来的字段可以填页面上的一行,下一课是数组,脚本里的活列表
🧠 测试您的知识
测试您的知识
通过这个互动测验挑战自己,看看你对这个主题的理解程度如何
📝 说明
- 仔细阅读每个问题
- 为每个问题选择最佳答案
- 您可以随时重新参加测验
- 您的进度将显示在顶部