JSON
语法
JSON 语法的类型:
- **简单值:**字符串、数值、布尔值和 null 可以在 JSON 中出现,特殊值 undefined 不可以。
- **对象:**第一种复杂数据类型,对象表示有序键/值对。每个值可以是简单值,也可以是复杂值。
- **数组:**第二种复杂数据类型,数组表示可以通过数值索引访问的值的有序列表。数组值可以是任意类型。
对象
JavaScript 的对象:
let xkcMsg = {
name: "小卡车",
age: 20,
};
JSON 表示的对象:
{
"name": "小卡车",
"age": 20
}
数组
JavaScript 的数组:
let hobby = ["LOL"];
JSON 表示的数组:
["LOL"]
对象和数组混合使用:
[
{
"id": 1,
"name": "小卡车",
"age": 20,
"hobby": ["LOL"]
},
{
"id": 2,
"name": "xkc",
"age": 20,
"hobby": ["看书"]
}
]
JSON 对象
JSON 对象有两个方法:stringify()
和 parse()
。分别可以将 JavaScript 序列化为 JSON 字符串;将 JSON 解析为原生 JavaScript 值。
let xkcMsg = {
name: "小卡车",
age: 20,
};
let jsonText = JSON.stringify(xkcMsg);
console.log(jsonText); // {"name":"小卡车","age":20}
let json = JSON.parse(jsonText);
console.log(json); // { name: '小卡车', age: 20 }
序列化选项
JSON.stringify()
方法除了要序列化的对象,还可以接收两个参数。第一个参数是过滤器,可以是数组或者函数;第二个参数是用于缩进结果 JOSN 字符串的选项。
过滤结果
如果第二个参数是数组,则执行 JSON.stringify()
方法会返回包含该数组中各个元素的对象属性。
let xkcMsg2 = {
name: "小卡车",
age: 20,
hobby: ["LOL"],
};
let jsonText2 = JSON.stringify(xkcMsg2, ["name", "hobby"]);
console.log(jsonText2); // {"name":"小卡车","hobby":["LOL"]}
如果第二个参数是一个函数。则提供的函数接收两个参数:属性名和属性值。
let xkcMsg3 = {
name: "xkc",
age: 18,
hobby: [],
};
let jsonText3 = JSON.stringify(xkcMsg3, (key, value) => {
switch (key) {
case "name":
return "小卡车";
case "age":
return 20;
case "hobby":
return value.concat("LOL");
default:
return value;
}
});
console.log(jsonText3); // {"name":"小卡车","age":20,"hobby":["LOL"]}
如果对象中有属性的值为 undefined 的话,该属性会被忽略。
let xkcMsg4 = {
name: "小卡车",
age: 20,
hobby: undefined,
};
let jsonText4 = JSON.stringify(xkcMsg4);
console.log(jsonText4); // {"name":"小卡车","age":20}
第三个参数是控制缩进和空格。如果参数是数值。最大缩进值是 10 ,大于 10 会自动设置为 10。
let xkcMsg5 = {
name: "小卡车",
age: 20,
hobby: undefined,
};
let jsonText5 = JSON.stringify(xkcMsg5, null, 4);
console.log(jsonText5);
/*
{
"name": "小卡车",
"age": 20
}
*/
第三个参数如果是字符串,则使用该字符串来进行缩进。
let xkcMsg6 = {
name: "小卡车",
age: 20,
hobby: undefined,
};
let jsonText6 = JSON.stringify(xkcMsg6, null, "--");
console.log(jsonText6);
/*
{
--"name": "小卡车",
--"age": 20
}
*/
toJSON() 方法
需要在 JSON.stringify() 之上自定义 JSON 序列化。可以在被序列化对象中添加 toJSON()
方法。
toJSON()
可以与过滤函数一起使用。
把对象传入 JSON.stringify()
时执行的步骤:
- 调用
toJSON()
方法获取实际的值,否则返回默认的序列化。 - 如果提供第二个参数,则传入过滤函数的值便是第 1 步骤中返回的值。
- 第 2 步骤返回的每个值进行相应的序列化。
- 如果提供第三个参数,则使用第三个参数进行缩进。
let xkcMsg1 = {
name: "xkc",
age: 20,
hobby: ["听歌", "LOL"],
test: undefined,
toJSON: function () {
console.log("xkcMsg1");
return this.hobby;
},
};
let jsonText1 = JSON.stringify(
xkcMsg1,
(key, value) => {
switch (value) {
case "LOL":
return "打" + value;
default:
return value;
}
},
2
);
console.log(jsonText1);
/*
xkcMsg1
[
"听歌",
"打LOL"
]
*/
解析选项
JSON.parse()
方法可以接收一个额外的参数,函数会针对每个键值都调用一次,为区别于传给 JSON.stringify()
的起过滤作用的替代函数,被成为还原函数。
如果还原函数中返回 undefined 则删除相应的键。
let xkcMsg7 = {
name: "小卡车",
age: 20,
hobby: ["LOL", "听歌"],
};
let jsonText7 = JSON.stringify(xkcMsg7);
let xkcMsg7New = JSON.parse(jsonText7, (key, value) => {
if (value === "LOL") {
return "打" + value ;
} else if (key === "age") {
return undefined;
} else {
return value;
}
});
console.log(xkcMsg7New);
/*
{ name: '小卡车', hobby: [ '打LOL', '听歌' ] }
*/