JSON 是一种数据格式,而不是一种编程语言。虽然与 JavaScript 具有相同的语法形式,但从不属于 JavaScript。很多编程语言都有针对 JSON 的解析器和序列化器。
语法
JSON 语法可以支持三种类型值,分别是简单值(string, number, boolean, null, 不支持undefined),对象和数组。
如果是简单值,注意如果是字符串时必须要用双引号而不能使用单引号。如下:
"Hello word!"
如果是对象,则对象的属性必须用双引号。如下:
{
"name": "xiaobai",
"age": 22
}
如果是数组,如下:
["xiaobai", "xiaohei", "xiaohong"]
三者组合起来可以成为很复杂的数据类型:
[
{
"title": "book1",
"authors": [
"xiaobai"
],
"year": 2013
}
{
"title": "book2",
"authors":[
"xiaohei", "xiaohong"
]
"year": 2013
}
]
JSON 序列化
JSON.stringify() 可以把一个 JavaScript 对象序列化为一个 JSON 字符串。另外还可以接受两个可选参数,第一个参数是一个过滤器,可以是一个
数组,也可以是一个函数;第二个参数是一个选项,表示是否在 JSON 字符串中保留缩进。
如果过滤器的参数是数组,那么 JSON.stringify() 将只列出数组中所列出的属性。
var person = {
"name": "xiaobai",
"sisters": [
"xiaohong", "xiaohei"
],
"age": 22
}
var jsonText = JSON.stringify(person,["name", "age"]);
因此,返回的字符串中,只会包含 name 和 age 这两个属性。
{"name":"xiaobai","age":22}
如果过滤器是一个函数,传入的函数接受两个参数,属性名和属性值。根据属性名可以直到如何处理序列化的对象中的属性。
var jsonText = JSON.stringify(person, function(key, value){
switch(key){
case "name":
return "new name";
case "sisters":
return value.join(",");
case "age":
return undefined;
default:
return value;
}
});
此时返回的字符串如下:
{"name":"new name", "sisters":"xiaohong,xiaohei"}
JSON.stringify() 的第三个参数可以控制结果中的缩进和空白符。如果第一个参数是一个数值,那么它表示缩进的空格数,例如:
var jsonText = JSON.stringify(book, null, 4);
则生成的字符串如下:
{
"name": "xiaobai",
"sisters" : [
"xiaohong", "xiaohei"
],
"age": 22
}
JSON.stringify() 自动在字符串中加入了换行符,最大缩进的空格数为10,所有大于10的值都会自动转换为10。
如果缩进的参数是一个字符串而非一个数值,那么这个字符串在 JSON 字符串中被用作缩进符。例如:
var jsonText = JSON.stringify(person, null, "--");
则生成的字符串变成了:
{
--"name": "xiaobai",
--"sisters": [
----"xiaohong", "xiaohei"
--]
--"age": 22
}
toJSON() 的方法
有时候,JSON.stringify() 并不能满足一些对象进行自定义序列化要求。这时,可以调用对象上的 toJSON() 的方法,返回其自定义的 JSON 格式。比如,Date 的对象就具有该方法,用户将其转换为一个日期字符串。例如:
var person = {
"name": "xiaobai",
"sisters": [
"xiaohong", "xiaohei"
],
"age": 22,
toJSON: function(){
return this.name;
}
};
var jsonText = JSON.stringify(person);
则生成的字符串中只包含了name的属性值。
toJSON() 可以作为函数过滤器的补充,因此理解序列化内部的顺序十分重要。
- 如果存在 toJSON() 的方法而且通过它能取的有效值,则调用该方法。否则按默认的顺序执行序列化。
- 如果提供了第二个参数,应用这个过滤器。传入过滤器的值是第一步返回的结果。
- 对第二步返回的每个值进行相应的序列化。
- 如果提供了第三个参数,执行相应的格式化。
解析
JSON.parse() 可以把 JSON 字符串解析为原生的 JavaScript 的值。该方法也接受一个可选参数,带参数是一个函数,通常称为还原函数,将在每个属性值上调用。该函数也接受两个参数,属性健和属性值,而且都需要返回一个值。
var book = {
title: "Professional JavaScript",
releaseDate: new Date(2011, 11, 1)
};
var jsonText = JSON.stringify(book);
var bookCopy = JSON.parse(jsonText, function(key, value){
if(key == "releaseDate"){
return new Date(value);
}else{
return value;
}
});