JSON是一种数据格式,JSON 并不从属于 JavaScript,很多编程语言都有针对 JSON 的解析器和序列化器。
语法
- 简单值:在 JSON 中表示字符串、数值、布尔值和 null,但不支持 JavaScript 中的特殊值 undefined。
// JSON字符串必须使用双引号
"Hello World"
- 对象:表示的是一组无序的键值对,属性的值可以是简单值,也可以是复杂类型值。
// JSON 中的对象要求必须给属性加双引号
{
"name": "Nicholas",
"age": 29
}
- 数组:表示一组有序的值的列表。
[{
"title": "Professional JavaScript",
"authors": ["Nicholas C. Zakas"],
"edition": 3,
"year": 2011
},{
"title": "Professional JavaScript",
"authors": ["Nicholas C. Zakas"],
"edition": 2,
"year": 2009
}]
解析与序列化
JSON 数据结构解析为有用的 JavaScript 对象。
JSON对象
JSON 对象有两个方法:stringify()和 parse()。
JSON.stringify() // 把 JavaScript 对象序列化为 JSON 字符串,默认情况输出的 JSON 字符串不包含任何空格字符或缩进
JSON.parse() // 把 JSON 字符串解析为原生 JavaScript 值
序列化选项
JSON.stringify()
除了要序列化的 JavaScript对象外,还可以接收另外两个参数,这两 个参数用于指定以不同的方式来序列化 JavaScript 对象。
JSON.stringify(param1, param2, param3)
// param1: javascript值
// param2: 见过滤结果
// param3: 见字符串缩进
- 过滤结果
// param2:第二个参数是数组
// 一个数组包含对象属性,在返回的结果字符串中,就只会包含定义的属性
var jsonObj = [{
"title": "Professional JavaScript",
"authors": ["Nicholas C. Zakas"],
"edition": 3,
"year": 2011
},{
"title": "Professional JavaScript",
"authors": ["Nicholas C. Zakas"],
"edition": 2,
"year": 2009
}]
var jsonText = JSON.stringify(jsonObj, ["title", "year"])
jsonText // "[{"title":"Professional JavaScript","year":2011},{"title":"Professional JavaScript","year":2009}]"
// param2:第二个参数是函数
// 传入的函数接收两个参数,属性(键)名和属性值。
// 属性名只能是字符串,而在值并非键值对儿结构的值时,键名可以是空字符串。
// 如果函数返回了undefined,那么相应的属性会被忽略。
var book = {
title: 'Professional JavaScript',
authors: ['Nicholas C. Zakas', 'Bob'],
edition: 3,
year: 2011
}
var bookStr = JSON.stringify(book, function(key, value) {
if (key === "authors") {
return value.join(",")
} else if (key === "year" || key === "edition") {
return undefined
} else {
return value
}
})
bookStr // "{"title":"Professional JavaScript","authors":"Nicholas C. Zakas,Bob"}"
- 字符串缩进
// parma3:第三个参数
// 如果这个参数是一个数值,那它表示的是每个级别缩进的空格数,并且字符串中插入了换行符以提高可读性。
var book = {
title: 'Professional JavaScript',
authors: ['Nicholas C. Zakas', 'Bob'],
edition: 3,
year: 2011
}
var jsonText = JSON.stringify(book, null, 4)
/** jsonText result
"{
"title": "Professional JavaScript",
"authors": [
"Nicholas C. Zakas",
"Bob"
],
"edition": 3,
"year": 2011
}"
*/
// parma3:第三个参数
// 如果这个参数是一个字符串,这个字符串将在 JSON 字符串中被用作缩进字符。
// 并且字符串中插入了换行符以提高可读性。
var book = {
title: 'Professional JavaScript',
authors: ['Nicholas C. Zakas', 'Bob'],
edition: 3,
year: 2011
}
var jsonText = JSON.stringify(book, null, '-')
/** jsonText result
"{
-"title": "Professional JavaScript",
-"authors": [
--"Nicholas C. Zakas",
--"Bob"
-],
-"edition": 3,
-"year": 2011
}"
*/
toJSON()
方法
可以为任何对象添加toJSON()
方法,用来作为函数过滤器的补充。
var book = {
title: 'Professional JavaScript',
authors: ['Nicholas C. Zakas', 'Bob'],
edition: 3,
year: 2011,
toJSON: function () {
return {
title: this.title
}
}
}
JSON.stringify(book) // "{"title":"Professional JavaScript"}"
把一个对象传 入 JSON.stringify(),序列化该对象的顺序如:
- 如果存在
toJSON()
方法而且能通过它取得有效的值,则调用该方法。否则,返回对象本身。 - 如果提供了第二个参数,应用这个函数过滤器。传入函数过滤器的值是第(1)步返回的值。
- 对第(2)步返回的每个值进行相应的序列化。
- 如果提供了第三个参数,执行相应的格式化。
解析选项
JSON.parse(param1, parma2)
// param1: JSON格式字符串
// param2: 还原函数,接收两个参数,一个键和一个值,并且要返回一个值
var book = {
title: 'Professional JavaScript',
year: 2011,
releaseDate: new Date(2011, 11, 1)
}
var jsonText = JSON.stringify(book); // "{"title":"Professional JavaScript","year":2011,"releaseDate":"2011-11-30T16:00:00.000Z"}"
var bookCopy = JSON.parse(jsonText, function(key, value){
if (key == "releaseDate"){
return new Date(value);
} else {
return value;
}
})
/** bookCopy result
{
releaseDate: Thu Dec 01 2011 00:00:00 GMT+0800 (CST),
title: "Professional JavaScript",
year: 2011
}
*/
兼容性
原生的 JSON 对象也得到了很多浏览器的支持,比如 IE8+、Firefox 3.5+、Safari 4+、Opera 10.5 和 Chrome。
对于不能支持原生json的浏览器可使用:https://github.com/douglascrockford/JSON-js