JSON详解
# 介绍
JSON: J
avaS
cript O
bject N
otation(JavaScript 对象表示法)
JSON 是存储和交换文本信息的语法,类似 XML。
JSON 比 XML 更小、更快,更易解析。
实例
{
"message": [
{ "name":"Jack" , "address":"A" },
{ "name":"Mary" , "address":"B" },
{ "name":"Tom" , "address":"C" }
]
}
2
3
4
5
6
7
关于 JSON,最重要的是要理解
它是一种数据格式,不是一种编程语言。虽然具有相同的语法形式,但 JSON 并不从属于 JavaScript。而且,并不是只有 JavaScript 才使用 JSON
,毕竟 JSON 只是一种数据格式。很多编程语言都有针对 JSON 的解析器和序列化器。JSON 是一个轻量级的数据格式,可以简化表示复杂数据结构的工作量。JSON 使用 JavaScript 语法的子集表示对象、数组、字符串、数值、布尔值和 null **。
即使 XML 也能表示同样复杂的数据结果,但JSON 没有那么烦琐,而且在 JavaScript 中使用更便利。ECMAScript 5 定义了一个原生的 JSON 对象; JSON对象包含两个方法: 用于解析 JavaScript Object Notation (opens new window) (JSON) 的
parse()
方法,以及将对象/值
转换为 JSON字符串的stringify()
方法。
# JSON语法
JSON 的语法可以表示以下三种类型
的值。
简单值:使用与 JavaScript 相同的语法,可以在 JSON 中表示字符串、数值、布尔值和 null 。但 JSON 不支持 JavaScript 中的特殊值 undefined 。
对象:对象作为一种复杂数据类型,表示的是一组无序的键值对儿。而每个键值对儿中的值可以是简单值,也可以是复杂数据类型的值。
数组:数组也是一种复杂数据类型,表示一组有序的值的列表,可以通过数值索引来访问其中的值。数组的值也可以是任意类型 ——
简单值
、对象
或数组
。 JavaScript 与 JSON 的区别
JavaScript类型 | JSON 的不同点 |
---|---|
对象和数组 | 属性名称必须是双引号括起来的字符串;最后一个属性后不能有逗号。 |
数值 | 禁止出现前导零( JSON.stringify 方法自动忽略前导零,而在 JSON.parse 方法中将会抛出 SyntaxError);如果有小数点, 则后面至少跟着一位数字。 |
字符串 | 只有有限的一些字符可能会被转义;禁止某些控制字符; Unicode 行分隔符 (U+2028 (opens new window))和段分隔符 (U+2029 (opens new window))被允许 ; 字符串必须用双引号括起来。请参考下面的示例 ,可以看到 JSON.parse() 能够正常解析,但将其当作JavaScript解析时会抛出 SyntaxError (opens new window) 错误: |
示例
let code = '"\u2028\u2029"';
JSON.parse(code); // 正常
eval(code); // 错误
2
3
语法
JSON 语法是 JavaScript 对象表示语法的子集。
数据在名称/值对中
数据由逗号分隔
大括号
{}
保存对象中括号
[]
保存数组,数组可以包含多个对象
书写格式
key : value
# 简单值
注意 字符串必须使用双引号("")
最简单的 JSON 数据形式就是简单值;
包括:字符串
、数值
(必须是十进制标识)、布尔值
和Null
// 字符串
{ "msg": "Hello JSON" }
// 数字(整数或浮点数)
{ "age": "18" }
// 布尔值
{ "flag": true }
// null
{ "money": null }
2
3
4
5
6
7
8
JSON 更多的是用来表示复杂的数据结构,简单值只是整个数据结构中的一部分。
# 对象
对象语法
{ "msg": "Hello JSON", "age": "18" }
访问对象值
- 使用点号(.)
let Obj, x;
Obj = { "msg": "Hello JSON", "age": "18" };
x = Obj.name; // Hello JSON
2
3
- 使用中括号([])
let Obj, x;
Obj = { "msg": "Hello JSON", "age": "18" };
x = Obj["name"]; // Hello JSON
2
3
嵌套
JSON 对象在大括号 {}
中书写,对象可以包含多个
名称/值对;
即JSON 对象中可以包含
另外一个 JSON 对象
示例
{
"name": "Mary",
"age": 18
"address": {
"name":"地址名"
"city": "广州市",
"location": "xx路XX号"
}
}
2
3
4
5
6
7
8
9
这里虽然出现两个 "name"
属性,但由于它们分别属于
不同的对象,因此这样完全没有问题。不过,同一个对象中绝对不应该出现两个同名属性。
# 数组
提示
JSON 数组在中括号 []
中书写
JSON 对象中的数组 对象属性的值可以是一个数组
{
"name": "Jack",
"age": 18,
"hobby": [ "eat", "sport", "drink" ]
}
2
3
4
5
访问数组值
使用索引值
let x = Obj.hobby[0] // eat
嵌套
JSON 对象中数组可以包含另外一个数组,或者另外一个 JSON 对象
myObj = {
"name": "Jack",
"age": 18,
"hobby": [
{ "name":"eat", "info":[ "米饭", "水果", "美食" ] },
{ "name":"sport", "info":[ "跑步", "游泳", "跳高" ] },
{ "name":"drink", "info":[ "果汁", "可乐" ] }
]
}
2
3
4
5
6
7
8
9
# 解析和序列化
JSON 对象有两个方法: stringify()
和 parse()
。在最简单的情况下,这两个方法分别用于把JavaScript 对象序列化
为 JSON 字符串和把 JSON 字符串解析
为原生 JavaScript 值。
# JSON.stringify()
用法 JSON对象转为JSON字符串(在向服务器发送数据
时一般是字符串)
假如我们向服务器发送以下数据
let JSONObj = {
title: "JSON",
authors: [
"Jack"
],
age: 18,
};
let JSONStr = JSON.stringify(JSONObj);
console.log(JSONStr); // {"title":"JSON","authors":["Jack"],"age":18}
console.log(typeof JSONObj); // object
console.log(typeof JSONStr); // string
2
3
4
5
6
7
8
9
10
11
默认情况下, JSON.stringify() 输出的 JSON 字符串不会存在空格字符
或缩进
异常
1. 解析数据
JSON 不能存储 Date 对象。
JSON.stringify() 会将所有日期转换为字符串。
var obj = { "name":"Jack", "initDate":new Date()};
var myJSON = JSON.stringify(obj); // {"name":"Jack","initDate":"2021-06-07T02:44:33.788Z"}
2
之后你可以再将字符串
转换为 Date
对象。
2. 解析函数
JSON 不允许包含函数
,JSON.stringify() 会删除 JavaScript 对象的函数,包括 key 和 value。除此之外undefined
也会被删除
let JSONObj = {
age: 18,
test1: undefined,
test2: function(){return 1+1}
};
let JSONStr = JSON.stringify(JSONObj);
console.log(JSONStr); // {"age":18}
2
3
4
5
6
7
在序列化 js 对象时,所有函数
及原型成员
都会被有意忽略,不体现在结果中。此外,值为 undefined
的任何属性也都会被跳过。结果都是值为有效
JSON 数据类型的实例属性。
上面的 test1
和 test2
将不会出现最终的结果中
接下来我们再看看另外两个参数(可选参数)
简单来说
replacer
可以充当一个过滤器的作用space
字符串缩进的作用
数组过滤
var book={
"title":"book title",
authors:[ "one", "two", "three" ],
edition:2,
year:2021
};
var JSONStr=JSON.stringify(book,["title","year","other"]);
console.log(JSONStr);//{"title":"book title","year":2021}
console.log(typeof JSONStr);//string
2
3
4
5
6
7
8
9
JSON.stringify() 的第二个参数是一个数组,其中包含三个字符串: "title"、"year"、"other"。这两个属性与将要序列化的对象中
的属性是对应
的,因此在返回的结果字符串中,就只会包含这两个属性
;因为源数据中没有other
这个键值对;匹配不到,就会忽略掉;
函数过滤
var book = {
"title": "JSON",
"authors": ["one", "two", "three"],
};
var JSONStr = JSON.stringify(book, function (key, value) {
switch (key) {
case "authors":
return value.join("+++++"); //如果键为 "authors" ,就将数组连接为一个字符串
// console.log(JSONStr);//{"title":"JSON","authors":"one+++++two+++++three",}
}
}
2
3
4
5
6
7
8
9
10
11
函数过滤器根据传入的键
来决定结果
字符串缩进
提示
如果 space 是一个数字
,则返回值文本在每个级别缩进指定数目
的空格
,如果 space 大于
10,则文本缩进 10
个空格(前10个)。
var book={
"title":"JSON",
authors:[
"one",
"two",
"three"
],
year:2021
};
var JSONStr=JSON.stringify(book,null,4);
console.log(JSONStr);
2
3
4
5
6
7
8
9
10
11
输出结果如下:
{
"title": "JSON",
"authors": [
"one",
"two",
"three"
],
"year": 2021
}
// 默认
{"title":"book title","authors":["one","two","three"],"year":2021}
2
3
4
5
6
7
8
9
10
11
12
也可以用字符替换空格
var JSONStr=JSON.stringify(book,null,"+ + ");
输出结果如下:
{
+ + "title": "JSON",
+ + "authors": [
+ + + + "one",
+ + + + "two",
+ + + + "three"
+ + ],
+ + "year": 2021
}
2
3
4
5
6
7
8
9
# JSON.parse()
用法 将数据转换为 JavaScript 对象(接收服务器数
据时一般是字符串)
var JSONStr1 = '{title: "JSON",authors: ["Jack"],age: 18}';
var JSONStr2 = '{"title": "JSON","authors": ["Jack"],"age": 18,year: 2021}';
var JSONStr3 = '{"title": "JSON","authors": ["Jack"],"age": 18}';
var JSONStr4 = '{"title": "JSON","authors": ["Jack"],"age": 18,"year": 2021,"testUndefined":undefined}';
//var JSONObj1 = JSON.parse(JSONStr1); // 报错啦,属性值没有""
//var JSONObj2 = JSON.parse(JSONStr2); // 报错啦,属性值没有全部用""
var JSONObj3 = JSON.parse(JSONStr3); // 成功
//var JSONObj4 = JSON.parse(JSONStr4); // 报错啦,不能含有undefined,function等数据
console.log(JSONObj3); //{"title":"JSON","authors":["Jack"],"age":18,"year":2021}
2
3
4
5
6
7
8
9
10
异常
1. 解析数据
与JSON.stringify()同样不能存储 Date 对象。
如果你需要存储 Date 对象,需要将其转换为字符串
。
之后再
将字符串转换为 Date 对象。
var text = '{ "name":"JSON", "initDate":"2021-06-18"}';
var obj = JSON.parse(text);
obj.initDate = new Date(obj.initDate);
console.log(obj); // {name: "Runoob", initDate: Fri Jun 18 2021 08:00:00 GMT+0800 (中国标准时间)}
2
3
4
2. 解析函数
JSON 不允许包含函数,但你可以将函数作为字符串存储,之后再将字符串转换为函数。
可选参数
var text = '{ "name":"JSON", "initDate":"2021-06-18"}';
var obj = JSON.parse(text, function (key, value) {
if (key == "initDate") {
return new Date(value);
} else {
return value;
}
});
console.log(obj); // {name: "JSON", initDate: Fri Jun 18 2021 08:00:00 GMT+0800 (中国标准时间)}
2
3
4
5
6
7
8
9