JSON 是一種數(shù)據(jù)格式,而不是一種編程語言。雖然與 JavaScript 具有相同的語法形式,但從不屬于 JavaScript臭挽。很多編程語言都有針對(duì) JSON 的解析器和序列化器。
語法
JSON 語法可以支持三種類型值咬腕,分別是簡(jiǎn)單值(string, number, boolean, null, 不支持undefined)欢峰,對(duì)象和數(shù)組。
如果是簡(jiǎn)單值涨共,注意如果是字符串時(shí)必須要用雙引號(hào)而不能使用單引號(hào)纽帖。如下:
"Hello word!"
如果是對(duì)象,則對(duì)象的屬性必須用雙引號(hào)举反。如下:
{
"name": "xiaobai",
"age": 22
}
如果是數(shù)組懊直,如下:
["xiaobai", "xiaohei", "xiaohong"]
三者組合起來可以成為很復(fù)雜的數(shù)據(jù)類型:
[
{
"title": "book1",
"authors": [
"xiaobai"
],
"year": 2013
}
{
"title": "book2",
"authors":[
"xiaohei", "xiaohong"
]
"year": 2013
}
]
JSON 序列化
JSON.stringify() 可以把一個(gè) JavaScript 對(duì)象序列化為一個(gè) JSON 字符串。另外還可以接受兩個(gè)可選參數(shù)火鼻,第一個(gè)參數(shù)是一個(gè)過濾器室囊,可以是一個(gè)
數(shù)組,也可以是一個(gè)函數(shù)魁索;第二個(gè)參數(shù)是一個(gè)選項(xiàng)融撞,表示是否在 JSON 字符串中保留縮進(jìn)。
如果過濾器的參數(shù)是數(shù)組粗蔚,那么 JSON.stringify() 將只列出數(shù)組中所列出的屬性尝偎。
var person = {
"name": "xiaobai",
"sisters": [
"xiaohong", "xiaohei"
],
"age": 22
}
var jsonText = JSON.stringify(person,["name", "age"]);
因此,返回的字符串中鹏控,只會(huì)包含 name 和 age 這兩個(gè)屬性致扯。
{"name":"xiaobai","age":22}
如果過濾器是一個(gè)函數(shù),傳入的函數(shù)接受兩個(gè)參數(shù)当辐,屬性名和屬性值急前。根據(jù)屬性名可以直到如何處理序列化的對(duì)象中的屬性。
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;
}
});
此時(shí)返回的字符串如下:
{"name":"new name", "sisters":"xiaohong,xiaohei"}
JSON.stringify() 的第三個(gè)參數(shù)可以控制結(jié)果中的縮進(jìn)和空白符瀑构。如果第一個(gè)參數(shù)是一個(gè)數(shù)值,那么它表示縮進(jìn)的空格數(shù)刨摩,例如:
var jsonText = JSON.stringify(book, null, 4);
則生成的字符串如下:
{
"name": "xiaobai",
"sisters" : [
"xiaohong", "xiaohei"
],
"age": 22
}
JSON.stringify() 自動(dòng)在字符串中加入了換行符寺晌,最大縮進(jìn)的空格數(shù)為10,所有大于10的值都會(huì)自動(dòng)轉(zhuǎn)換為10。
如果縮進(jìn)的參數(shù)是一個(gè)字符串而非一個(gè)數(shù)值澡刹,那么這個(gè)字符串在 JSON 字符串中被用作縮進(jìn)符呻征。例如:
var jsonText = JSON.stringify(person, null, "--");
則生成的字符串變成了:
{
--"name": "xiaobai",
--"sisters": [
----"xiaohong", "xiaohei"
--]
--"age": 22
}
toJSON() 的方法
有時(shí)候,JSON.stringify() 并不能滿足一些對(duì)象進(jìn)行自定義序列化要求罢浇。這時(shí)陆赋,可以調(diào)用對(duì)象上的 toJSON() 的方法沐祷,返回其自定義的 JSON 格式。比如攒岛,Date 的對(duì)象就具有該方法赖临,用戶將其轉(zhuǎn)換為一個(gè)日期字符串。例如:
var person = {
"name": "xiaobai",
"sisters": [
"xiaohong", "xiaohei"
],
"age": 22,
toJSON: function(){
return this.name;
}
};
var jsonText = JSON.stringify(person);
則生成的字符串中只包含了name的屬性值灾锯。
toJSON() 可以作為函數(shù)過濾器的補(bǔ)充兢榨,因此理解序列化內(nèi)部的順序十分重要。
- 如果存在 toJSON() 的方法而且通過它能取的有效值,則調(diào)用該方法顺饮。否則按默認(rèn)的順序執(zhí)行序列化吵聪。
- 如果提供了第二個(gè)參數(shù),應(yīng)用這個(gè)過濾器兼雄。傳入過濾器的值是第一步返回的結(jié)果吟逝。
- 對(duì)第二步返回的每個(gè)值進(jìn)行相應(yīng)的序列化。
- 如果提供了第三個(gè)參數(shù)赦肋,執(zhí)行相應(yīng)的格式化块攒。
解析
JSON.parse() 可以把 JSON 字符串解析為原生的 JavaScript 的值。該方法也接受一個(gè)可選參數(shù)金砍,帶參數(shù)是一個(gè)函數(shù)局蚀,通常稱為還原函數(shù),將在每個(gè)屬性值上調(diào)用恕稠。該函數(shù)也接受兩個(gè)參數(shù)琅绅,屬性健和屬性值,而且都需要返回一個(gè)值鹅巍。
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;
}
});