本文輸出和JSON有關(guān)的以下內(nèi)容
? JSON和javaScript
? JSON的語(yǔ)法介紹
? JSON的數(shù)據(jù)類型
? JSON和XMLHTTPRequest
? JSON的序列化和反序列化處理
1.1 JSON和javaScript
JSON是一種數(shù)據(jù)交換格式。
JSON的全稱是JavaScript Object Notation,翻譯為JavaScript對(duì)象表示法俗壹。JSON的這個(gè)全稱猫缭,無(wú)疑讓很多人既興奮又困惑,興奮的人直接認(rèn)為這就是JavaScript中的對(duì)象叼屠,困惑的人覺(jué)察出JSON數(shù)據(jù)和JavaScript對(duì)象好像有些不一樣。接下來(lái)我們先談一談JSON數(shù)據(jù)和JavaScript的關(guān)系。
誠(chéng)然撑瞧,從JSON的全稱可以看出JSON和JavaScript語(yǔ)言必定有種某種神秘關(guān)聯(lián),至少能夠確定的是JSON的命名確實(shí)來(lái)源于JavaScript這門語(yǔ)言显蝌。
JSON基于JavaScript對(duì)象字面量预伺,但JSON本身是一種數(shù)據(jù)交換格式,因此它是獨(dú)立于語(yǔ)言的曼尊。JSON全稱為JavaScript對(duì)象表示法酬诀,在理解的時(shí)候可以認(rèn)為JSON ==> JavaScript && 對(duì)象 && 表示法
JavaScript我們知道是一門動(dòng)態(tài)腳本語(yǔ)言,那么對(duì)象表示法
是什么涩禀?
對(duì)象是面向?qū)ο缶幊陶Z(yǔ)言中一種常見的數(shù)據(jù)類型料滥,表示鍵值對(duì)的集合,那么表示法
是什么艾船?
表示法:是指一個(gè)可以表示諸如數(shù)字或單詞等數(shù)據(jù)的字符系統(tǒng)葵腹。
JSON起源于JavaScript(靈感來(lái)源于JavaScript的對(duì)象語(yǔ)法),但真正重要的是具體的表示法本身屿岂。JSON不僅獨(dú)立于語(yǔ)言践宴,而且使用了一種在許多編程語(yǔ)言中能夠找到共同元素的表達(dá)方式∫常基于這種簡(jiǎn)潔的表達(dá)方式阻肩,JSON迅速成為一種流行的數(shù)據(jù)交換格式。目前运授,客戶端和服務(wù)器端在進(jìn)行數(shù)據(jù)通信的時(shí)候烤惊,常見的數(shù)據(jù)格式就是JSON和XML。
1.2 JSON的語(yǔ)法介紹
1.2.1 JSON的語(yǔ)法
JSON因?yàn)榛贘avaScript的字面量吁朦,所以我們先來(lái)看下JavaScript字面量的樣子柒室,下面給出簡(jiǎn)單的代碼示例,描述了一個(gè)書對(duì)象逗宜。
var book = {
name:"聲名狼藉者的生活",
price:42.00,
author:"感塾遥柯",
press:"北京大學(xué)出版社",
read:function () {
console.log("我的書名為:聲名狼藉者的的生活,作者為福柯....");
}
};
順便貼出一個(gè)簡(jiǎn)短的JSON數(shù)據(jù)
{
"name":"聲名狼藉者的生活",
"price":42.00,
"author":"阜慕玻柯",
"press":"北京大學(xué)出版社",
"content":["a","b","c",123]
}
我們可以對(duì)比下上面的JavaScript對(duì)象和JSON數(shù)據(jù)擂仍,會(huì)發(fā)現(xiàn)它們的結(jié)構(gòu)和語(yǔ)法形式很像,都是鍵值對(duì)的集合熬甚,接下來(lái)我們做更詳細(xì)的說(shuō)明逢渔。JSON數(shù)據(jù)在表達(dá)上和對(duì)象保持一致,但因?yàn)閿?shù)據(jù)交換格式的核心是數(shù)據(jù)乡括,所以JSON并不會(huì)保存函數(shù)等信息
肃廓。JSON數(shù)據(jù)所基于的JavaScript對(duì)象字面量單純指對(duì)象字面量以及其屬性的語(yǔ)法表示冲簿。
JSON的主要語(yǔ)法特點(diǎn)
① 以鍵值對(duì)的方式來(lái)保存數(shù)據(jù)
② 標(biāo)準(zhǔn)的JSON數(shù)據(jù)的key必須要使用雙引號(hào)包裹
③ { } 用于表示和存放對(duì)象,[ ] 用于表示和存放數(shù)組數(shù)據(jù)
JSON數(shù)據(jù)的讀取亿昏,在讀取JSON的時(shí)候
{ 表示開始讀取對(duì)象峦剔,} 表示對(duì)象讀取結(jié)束
[ 表示開始讀取數(shù)組,] 表示數(shù)組讀取結(jié)束
:用于分隔鍵值對(duì)中的key和value
, 用于分隔對(duì)象中的多個(gè)鍵值對(duì)或者是數(shù)組中的多個(gè)元素
JavaScript對(duì)象字面量中的key可以使用單引號(hào)角钩,可以使用雙引號(hào)吝沫,可以不必加上引號(hào)包裹,但是在JSON中递礼,所有的key必須要加上雙引號(hào)惨险。
1.2.2 JSON的驗(yàn)證和格式化工具
下面列出一些能夠?qū)SON數(shù)據(jù)進(jìn)行校驗(yàn)和格式化的在線地址
https://jsonlint.com/
http://tool.oschina.net/codeformat/json
https://jsonformatter.curiousconcept.com/
1.2.3 JSON文件和MIME類型
在開發(fā)中我們經(jīng)常需要處理大量的JSON數(shù)據(jù),JSON這種數(shù)據(jù)交換格式可以作為獨(dú)立的文件存在于文件系統(tǒng)中脊髓,文件擴(kuò)展名為 .json
JSON的MIME類型是application/json
, 詳細(xì)信息請(qǐng)參考IANA官網(wǎng)維護(hù)的所有媒體類型列表辫愉。
1.3 JSON的數(shù)據(jù)類型
JSON中(作為value值)的數(shù)據(jù)類型包括對(duì)象、字符串将硝、數(shù)字恭朗、布爾值、null和數(shù)組六種
依疼。
① 字符串
JSON中的字符串可以由任何的Unicode字符構(gòu)成痰腮,字符串的兩邊必須被雙引號(hào)包裹。需要注意的是:雖然在JavaScript語(yǔ)言中字符串可以使用單引號(hào)來(lái)包裹律罢,但是在JSON中的字符串必須使用雙引號(hào)包裹膀值。
如果字符串中存在以下特殊字符,那么需要在它們的前面加上一個(gè)反斜線(\)來(lái)進(jìn)行轉(zhuǎn)義误辑。
- " 雙引號(hào)
- \ 反斜線
- \/ 正斜線
- \b 退格符
- \f 換頁(yè)符
- \t 制表符
- \n 換行符
- \r 回車符
- \u 后面跟16進(jìn)制字符
② 數(shù)字
JSON中的數(shù)字可以是整數(shù)沧踏、小數(shù)、負(fù)數(shù)或者是指數(shù)巾钉。
③ 布爾類型
JSON數(shù)據(jù)僅僅支持小寫形式的布爾類型值:true 和 false翘狱。
④ null類型
JSON中沒(méi)有undefined這種數(shù)據(jù)類型,它使用null表示空睛琳,并且必須小寫盒蟆。
在JavaScript語(yǔ)言中踏烙,var obj = null 表示把obj這個(gè)對(duì)象清空师骗,它和undefined不太一樣,null表示什么都沒(méi)有讨惩,undefined表示未定義辟癌。
⑤ 對(duì)象類型
對(duì)象類型是使用逗號(hào)分隔的鍵值對(duì)的集合,使用大括號(hào)({}
)裹荐捻。
⑥ 數(shù)組類型
數(shù)組類型是元素的集合黍少,每個(gè)元素都可以是字符串寡夹、數(shù)字、布爾值厂置、對(duì)象或者數(shù)組中的任何一種菩掏。元素與元素之間使用逗號(hào)隔開,所有的元素被方括號(hào)([]
)包裹昵济,建議數(shù)組中所有的元素都應(yīng)該是相同數(shù)據(jù)類型的智绸。
1.4 JSON和XMLHTTPRequest
在前端開發(fā)中有一種發(fā)送網(wǎng)絡(luò)請(qǐng)求的技術(shù)Ajax,它可以實(shí)現(xiàn)異步處理網(wǎng)絡(luò)通信而不刷新頁(yè)面访忿。
Ajax的全稱為Asynchronous JavaScript and XML瞧栗,即異步的JavaScript和XML。我們知道JSON的定位是輕量級(jí)的數(shù)據(jù)交互格式海铆,客戶端在和服務(wù)器端進(jìn)行網(wǎng)絡(luò)通信的時(shí)候迹恐,服務(wù)器端返回給我們的數(shù)據(jù)大多數(shù)是JSON或者是XML。也就是說(shuō)JSON數(shù)據(jù)在Ajax網(wǎng)絡(luò)通信中可能扮演重要的角色卧斟,那什么Ajax不叫異步的JSON而叫做異步的XML呢殴边?
答案是:因?yàn)閯偺岢鲞@種網(wǎng)絡(luò)請(qǐng)求技術(shù)的時(shí)候,XML相比JSON更流行珍语。
在Ajax網(wǎng)絡(luò)請(qǐng)求中用到的核心對(duì)象XMLHTTPRequest也是如此找都,其實(shí)這個(gè)對(duì)象命名中包含XML也僅僅是因?yàn)閷?duì)于當(dāng)時(shí)而言,XML是網(wǎng)絡(luò)請(qǐng)求中最常用的數(shù)據(jù)交換格式廊酣。如果放在今天能耻,那么它們的名字應(yīng)該叫做AjaJ(Asynchronous JavaScript and JSON)和JSONHTTPRequest更合適一些。
1.5 JavaScript中JSON數(shù)據(jù)的序列化和反序列化處理
在網(wǎng)絡(luò)請(qǐng)求中亡驰,如果服務(wù)器返回給我們的數(shù)據(jù)是JSON數(shù)據(jù)晓猛,那么為了方便對(duì)數(shù)據(jù)的操作,通常我們?cè)诰W(wǎng)絡(luò)請(qǐng)求成功拿到JSON數(shù)據(jù)之后會(huì)先對(duì)JSON數(shù)據(jù)進(jìn)行反序列化操作凡辱。
在前端開發(fā)中戒职,早期的JSON解析基本上由eval函數(shù)來(lái)完成,ECMAScript5對(duì)解析JSON的行為進(jìn)行了規(guī)范透乾,定義了全局對(duì)象JSON洪燥。目前IE8+、FireFox 3.5+乳乌、Opera 10.5捧韵、Safari 4+和Chrome等瀏覽器均支持原生的JSON全局對(duì)象。
JSON數(shù)據(jù)的處理主要涉及到兩方面:序列化處理和反序列化處理
1.5.1 使用eavl函數(shù)來(lái)處理JSON數(shù)據(jù)
eavl函數(shù)說(shuō)明
JavaScript語(yǔ)言中eavl函數(shù)可以把字符串轉(zhuǎn)換為js的代碼并且馬上執(zhí)行汉操,使用情況和Function構(gòu)造函數(shù)用法類型再来。
eval("var a = 123;");
console.log(a + 1); //輸出結(jié)果為124
因?yàn)閺哪撤N程度上來(lái)講,json其實(shí)是JavaScript語(yǔ)言的嚴(yán)格子集,所以我們可以直接通過(guò)eval函數(shù)來(lái)對(duì)json數(shù)據(jù)進(jìn)行解析芒篷。需要注意的是搜变,使用eavl函數(shù)來(lái)對(duì)json數(shù)據(jù)結(jié)構(gòu)求值存在風(fēng)險(xiǎn),因?yàn)榭赡軙?huì)執(zhí)行一些惡意代碼针炉。
eavl函數(shù)解析JSON
服務(wù)器返回給前端的json數(shù)據(jù)可能是{...}
形式的挠他,也可能是[...]
形式的,分別對(duì)應(yīng)js中的對(duì)象和數(shù)組篡帕。如果是{...}
形式的绩社,那么在解析的時(shí)候,如果直接以eval(json)的方式處理會(huì)報(bào)錯(cuò)赂苗,因?yàn)閖s中不允許直接寫{name:"zs"}類似的語(yǔ)句愉耙。遇到這種結(jié)構(gòu)的json數(shù)據(jù),通常我們有兩種方式進(jìn)行處理:① 包裝成表達(dá)式 ② 賦值給變量拌滋。
//001 [...] 格式的json數(shù)據(jù)
var arrJson= '[{"name":"zs","age":18},{"name":"lisi","age":28}]';
var jsonArr = eval(arrJson);
//002 {...} 格式的json數(shù)據(jù)
var objJson = `{"name":"wendingding","age":18,"contentAbout":["JavaScript","CSS","HTML"],"car":{"number":"粵A6666","color":"red"}}`;
//eval(json); 錯(cuò)誤的演示:報(bào)錯(cuò)
//處理方式(1):以拼接的方式賦值給變量
eval("var jsonObj1 = " + objJson);
//處理方式(2):包裝成表達(dá)式
var jsonObj2 = eval("(" + objJson +")");
//打印轉(zhuǎn)換后得到的數(shù)組|對(duì)象
console.log(jsonArr);
console.log(jsonObj1);
console.log(jsonObj2);
1.5.2 使用JSON全局對(duì)象來(lái)處理JSON數(shù)據(jù)
JSON全局對(duì)象擁有兩個(gè)方法:stringify()和parse()朴沿,其中parse方法用于把json數(shù)據(jù)反序列化為原生的js,stringify方法用于把js對(duì)象序列化為json字符串败砂。
parse方法的使用
語(yǔ)法:JSON.parse(jsonString,[fn])
參數(shù)說(shuō)明
第一個(gè)參數(shù):jsonString為要解析的json字符串
第二個(gè)參數(shù):fn是一個(gè)可選參數(shù)赌渣,該參數(shù)為函數(shù)類型,接收兩個(gè)參數(shù)昌犹,分別是每個(gè)鍵值對(duì)的key和value坚芜。
//json字符串
var objJson = `{"name":"wendingding","age":18,"contentAbout":["JavaScript","CSS","HTML"],"car":{"number":"粵A6666","color":"red"}}`;
//把json字符串轉(zhuǎn)換為js數(shù)組
var arrJson= '[{"name":"zs","age":18},{"name":"lisi","age":28}]';
//把json字符串轉(zhuǎn)換為js對(duì)象
var jsonObj = JSON.parse(objJson);
var jsonArr = JSON.parse(arrJson);
console.log(jsonObj);
console.log(jsonArr);
//演示parse方法中函數(shù)參數(shù)的使用
function fn(key, value) {
if (key === "name") {
return value + "++" //在原有value值的基礎(chǔ)上拼接++字符串
} else if (key === "age") {
return undefined //如果返回undefined,則表示刪除對(duì)應(yīng)的鍵值對(duì)
} else {
return value //正常返回對(duì)應(yīng)的value值
}
}
console.log(JSON.parse(objJson, fn));
stringify方法使用說(shuō)明
語(yǔ)法:JSON.stringify(Obj,[fn|arr],[space])
參數(shù)說(shuō)明
第一個(gè)參數(shù):Obj為要進(jìn)行序列化操作的JavaScript對(duì)象
第二個(gè)參數(shù):過(guò)濾器斜姥,可以是函數(shù)或者是一個(gè)數(shù)組
第三個(gè)參數(shù):是否在生成的json字符串中保留縮進(jìn)鸿竖,用于控制縮進(jìn)的字符
//js中的普通對(duì)象
var obj = {
name:"zs",
age:18,
friends:["小霸王","花仙子","奧特曼"],
other:undefined,
showName:function () {
console.log(this.name);
}
};
//把js中的對(duì)象轉(zhuǎn)換為json字符串
//注意:
//001 如果鍵值對(duì)中存在value值為undefined的數(shù)據(jù),那么會(huì)被跳過(guò)
//002 對(duì)象中的方法以及該對(duì)象的原型成員數(shù)據(jù)在進(jìn)行轉(zhuǎn)換的時(shí)候铸敏,會(huì)被有意忽略
console.log(JSON.stringify(obj));
//控制縮進(jìn)缚忧,該參數(shù)的值可以是數(shù)字也可以是字符串,自動(dòng)換行
//001 如果是字符串那么會(huì)把對(duì)應(yīng)的字符拼接在鍵值對(duì)前面杈笔,超過(guò)10個(gè)字符的省略
//002 如果是數(shù)字那么會(huì)設(shè)置對(duì)應(yīng)的縮進(jìn)闪水,最多為10,超過(guò)則默認(rèn)為10
console.log(JSON.stringify(obj, null, 4));
console.log(JSON.stringify(obj, null, "@@"));
//過(guò)濾器(數(shù)組):表示只處理key為name和age這兩個(gè)鍵值對(duì)
console.log(JSON.stringify(obj, ["name","age"]));
//過(guò)濾器(函數(shù)):
function fn(key,value) {
if (key === "age")
{
return value + 20;
}else if (key === "name")
{
return undefined; //過(guò)濾掉key為name這個(gè)鍵值對(duì)
}else
{
return value;
}
}
console.log(JSON.stringify(obj,fn));
JSON數(shù)據(jù)總結(jié)
? JSON全稱是JavaScript Object Notation基于JavaScript蒙具,是JavaScript的子集球榆。
? JSON雖然是JavaScript的子集,但并不從屬于JavaScript禁筏,它獨(dú)立于語(yǔ)言持钉。
? JSON是用來(lái)表示和傳輸數(shù)據(jù)的格式,比XML更輕量級(jí)融师,現(xiàn)已成為web數(shù)據(jù)交換的事實(shí)標(biāo)準(zhǔn)右钾。
? JSON的優(yōu)勢(shì)在于其可以方便的把JSON字符串?dāng)?shù)據(jù)轉(zhuǎn)換為對(duì)應(yīng)的對(duì)象蚁吝,比XML更方便且數(shù)據(jù)更小旱爆。
? JSON語(yǔ)法可以表示:字符串舀射、數(shù)值、布爾值怀伦、null脆烟、對(duì)象和數(shù)組6種類型的值,不支持undefined房待。
? JSON中的"鍵"區(qū)別于JavaScript邢羔,必須要加上雙引號(hào)。
? JSON解析可以使用傳統(tǒng)的eval函數(shù)桑孩,或ECMAScript5推出的全局對(duì)象來(lái)處理拜鹤。
參考資料
JSON官網(wǎng):http://json.org/
JSON維基百科:https://en.wikipedia.org/wiki/JSON
JSON作者簡(jiǎn)介:https://en.wikipedia.org/wiki/Douglas_Crockford
JSON必知必會(huì):https://book.douban.com/subject/26789960/
JavaScript高級(jí)程序設(shè)計(jì):https://book.douban.com/subject/10546125/