javaScript系列[05]-javaScript和JSON

文頂頂水水發表於2018-06-19

本文輸出和JSON有關的以下內容
JSON和javaScript
JSON的語法介紹
JSON的資料型別
JSON和XMLHTTPRequest
JSON的序列化和反序列化處理

1.1 JSON和javaScript

JSON是一種資料交換格式。

JSON的全稱是JavaScript Object Notation,翻譯為JavaScript物件表示法。JSON的這個全稱,無疑讓很多人既興奮又困惑,興奮的人直接認為這就是JavaScript中的物件,困惑的人覺察出JSON資料和JavaScript物件好像有些不一樣。接下來我們先談一談JSON資料和JavaScript的關係。

誠然,從JSON的全稱可以看出JSON和JavaScript語言必定有種某種神祕關聯,至少能夠確定的是JSON的命名確實來源於JavaScript這門語言。

JSON基於JavaScript物件字面量,但JSON本身是一種資料交換格式,因此它是獨立於語言的。JSON全稱為JavaScript物件表示法,在理解的時候可以認為JSON ==> JavaScript && 物件 && 表示法

JavaScript我們知道是一門動態指令碼語言,那麼物件表示法是什麼?

物件是物件導向程式語言中一種常見的資料型別,表示鍵值對的集合,那麼表示法是什麼?

表示法:是指一個可以表示諸如數字或單詞等資料的字元系統。

JSON起源於JavaScript(靈感來源於JavaScript的物件語法),但真正重要的是具體的表示法本身。JSON不僅獨立於語言,而且使用了一種在許多程式語言中能夠找到共同元素的表達方式。基於這種簡潔的表達方式,JSON迅速成為一種流行的資料交換格式。目前,客戶端和伺服器端在進行資料通訊的時候,常見的資料格式就是JSON和XML。

1.2 JSON的語法介紹

1.2.1 JSON的語法

JSON因為基於JavaScript的字面量,所以我們先來看下JavaScript字面量的樣子,下面給出簡單的程式碼示例,描述了一個書物件。

1 var book = {
2 name:"聲名狼藉者的生活",
3 price:42.00,
4 author:"福柯",
5 press:"北京大學出版社",
6 read:function () {
7 console.log("我的書名為:聲名狼藉者的的生活,作者為福柯....");
8 }
9 };

順便貼出一個簡短的JSON資料

{
"name":"聲名狼藉者的生活",
"price":42.00,
"author":"福柯",
"press":"北京大學出版社",
"content":["a","b","c",123]
}

我們可以對比下上面的JavaScript物件和JSON資料,會發現它們的結構和語法形式很像,都是鍵值對的集合,接下來我們做更詳細的說明。JSON資料在表達上和物件保持一致,但因為資料交換格式的核心是資料,所以JSON並不會儲存函式等資訊。JSON資料所基於的JavaScript物件字面量單純指物件字面量以及其屬性的語法表示。

JSON的主要語法特點

① 以鍵值對的方式來儲存資料
② 標準的JSON資料的key必須要使用雙引號包裹
③ { } 用於表示和存放物件,[ ] 用於表示和存放陣列資料

JSON資料的讀取,在讀取JSON的時候

{ 表示開始讀取物件,} 表示物件讀取結束
[ 表示開始讀取陣列,] 表示陣列讀取結束
:用於分隔鍵值對中的key和value
, 用於分隔物件中的多個鍵值對或者是陣列中的多個元素
JavaScript物件字面量中的key可以使用單引號,可以使用雙引號,可以不必加上引號包裹,但是在JSON中,所有的key必須要加上雙引號。

1.2.2 JSON的驗證和格式化工具

下面列出一些能夠對JSON資料進行校驗和格式化的線上地址
https://jsonlint.com/
http://tool.oschina.net/codeformat/json
https://jsonformatter.curiousconcept.com/

1.2.3 JSON檔案和MIME型別

在開發中我們經常需要處理大量的JSON資料,JSON這種資料交換格式可以作為獨立的檔案存在於檔案系統中,副檔名為 .json

JSON的MIME型別是application/json, 詳細資訊請參考IANA官網維護的所有媒體型別列表

1.3 JSON的資料型別

JSON中(作為value值)的資料型別包括物件、字串、數字、布林值、null和陣列六種

① 字串
JSON中的字串可以由任何的Unicode字元構成,字串的兩邊必須被雙引號包裹。需要注意的是:雖然在JavaScript語言中字串可以使用單引號來包裹,但是在JSON中的字串必須使用雙引號包裹。

如果字串中存在以下特殊字元,那麼需要在它們的前面加上一個反斜線()來進行轉義。

– ” 雙引號
– 反斜線
– / 正斜線
– 退格符
– f 換頁符
– 製表符

換行符

回車符
– u 後面跟16進位制字元

 

② 數字
JSON中的數字可以是整數、小數、負數或者是指數。

③ 布林型別
JSON資料僅僅支援小寫形式的布林型別值:true 和 false。

④ null型別
JSON中沒有undefined這種資料型別,它使用null表示空,並且必須小寫。
在JavaScript語言中,var obj = null 表示把obj這個物件清空,它和undefined不太一樣,null表示什麼都沒有,undefined表示未定義。

⑤ 物件型別
物件型別是使用逗號分隔的鍵值對的集合,使用大括號({})裹。

⑥ 陣列型別
陣列型別是元素的集合,每個元素都可以是字串、數字、布林值、物件或者陣列中的任何一種。元素與元素之間使用逗號隔開,所有的元素被方括號([])包裹,建議陣列中所有的元素都應該是相同資料型別的。

1.4 JSON和XMLHTTPRequest

在前端開發中有一種傳送網路請求的技術Ajax,它可以實現非同步處理網路通訊而不重新整理頁面。

Ajax的全稱為Asynchronous JavaScript and XML,即非同步的JavaScript和XML。我們知道JSON的定位是輕量級的資料互動格式,客戶端在和伺服器端進行網路通訊的時候,伺服器端返回給我們的資料大多數是JSON或者是XML。也就是說JSON資料在Ajax網路通訊中可能扮演重要的角色,那什麼Ajax不叫非同步的JSON而叫做非同步的XML呢? 答案是:因為剛提出這種網路請求技術的時候,XML相比JSON更流行。

在Ajax網路請求中用到的核心物件XMLHTTPRequest也是如此,其實這個物件命名中包含XML也僅僅是因為對於當時而言,XML是網路請求中最常用的資料交換格式。如果放在今天,那麼它們的名字應該叫做AjaJ(Asynchronous JavaScript and JSON)和JSONHTTPRequest更合適一些。

1.5 JavaScript中JSON資料的序列化和反序列化處理

在網路請求中,如果伺服器返回給我們的資料是JSON資料,那麼為了方便對資料的操作,通常我們在網路請求成功拿到JSON資料之後會先對JSON資料進行反序列化操作。
在前端開發中,早期的JSON解析基本上由eval函式來完成,ECMAScript5對解析JSON的行為進行了規範,定義了全域性物件JSON。目前IE8+、FireFox 3.5+、Opera 10.5、Safari 4+和Chrome等瀏覽器均支援原生的JSON全域性物件。

JSON資料的處理主要涉及到兩方面:序列化處理和反序列化處理

1.5.1 使用eavl函式來處理JSON資料

eavl函式說明

JavaScript語言中eavl函式可以把字串轉換為js的程式碼並且馬上執行,使用情況和Function建構函式用法型別。

eval("var a = 123;");
console.log(a + 1); //輸出結果為124

因為從某種程度上來講,json其實是JavaScript語言的嚴格子集,所以我們可以直接通過eval函式來對json資料進行解析。需要注意的是,使用eavl函式來對json資料結構求值存在風險,因為可能會執行一些惡意程式碼。 

eavl函式解析JSON

伺服器返回給前端的json資料可能是{...}形式的,也可能是[...]形式的,分別對應js中的物件和陣列。如果是{...}形式的,那麼在解析的時候,如果直接以eval(json)的方式處理會報錯,因為js中不允許直接寫{name:”zs”}類似的語句。遇到這種結構的json資料,通常我們有兩種方式進行處理:① 包裝成表示式 ② 賦值給變數。

 1  
 2 //001 [...] 格式的json資料
 3 var arrJson= `[{"name":"zs","age":18},{"name":"lisi","age":28}]`;
 4 var jsonArr = eval(arrJson);
 5  
 6 //002 {...} 格式的json資料
 7 var objJson = `{"name":"wendingding","age":18,"contentAbout":["JavaScript","CSS","HTML"],"car":{"number":"粵A6666","color":"red"}}`;
 8  
 9 //eval(json); 錯誤的演示:報錯
10 //處理方式(1):以拼接的方式賦值給變數
11 eval("var jsonObj1 = " + objJson);
12 //處理方式(2):包裝成表示式
13 var jsonObj2 = eval("(" + objJson +")");
14  
15 //列印轉換後得到的陣列|物件
16 console.log(jsonArr);
17 console.log(jsonObj1);
18 console.log(jsonObj2);

 

1.5.2 使用JSON全域性物件來處理JSON資料

JSON全域性物件擁有兩個方法:stringify()和parse(),其中parse方法用於把json資料反序列化為原生的js,stringify方法用於把js物件序列化為json字串。

parse方法的使用
語法:JSON.parse(jsonString,[fn])

引數說明

第一個引數:jsonString為要解析的json字串
第二個引數:fn是一個可選引數,該引數為函式型別,接收兩個引數,分別是每個鍵值對的key和value。

 1  
 2 //json字串
 3 var objJson = `{"name":"wendingding","age":18,"contentAbout":["JavaScript","CSS","HTML"],"car":{"number":"粵A6666","color":"red"}}`;
 4  
 5 //把json字串轉換為js陣列
 6 var arrJson= `[{"name":"zs","age":18},{"name":"lisi","age":28}]`;
 7  
 8 //把json字串轉換為js物件
 9 var jsonObj = JSON.parse(objJson);
10 var jsonArr = JSON.parse(arrJson);
11 console.log(jsonObj);
12 console.log(jsonArr);
13  
14 //演示parse方法中函式引數的使用
15 function fn(key, value) {
16 if (key === "name") {
17 return value + "++" //在原有value值的基礎上拼接++字串
18 } else if (key === "age") {
19 return undefined //如果返回undefined,則表示刪除對應的鍵值對
20 } else {
21 return value //正常返回對應的value值
22 }
23 }
24 console.log(JSON.parse(objJson, fn));

stringify方法使用說明

語法:JSON.stringify(Obj,[fn|arr],[space])

引數說明

第一個引數:Obj為要進行序列化操作的JavaScript物件
第二個引數:過濾器,可以是函式或者是一個陣列
第三個引數:是否在生成的json字串中保留縮排,用於控制縮排的字元

 1 //js中的普通物件
 2 var obj = {
 3 name:"zs",
 4 age:18,
 5 friends:["小霸王","花仙子","奧特曼"],
 6 other:undefined,
 7 showName:function () {
 8 console.log(this.name);
 9 }
10  
11 };
12  
13 //把js中的物件轉換為json字串
14 //注意:
15 //001 如果鍵值對中存在value值為undefined的資料,那麼會被跳過
16 //002 物件中的方法以及該物件的原型成員資料在進行轉換的時候,會被有意忽略
17 console.log(JSON.stringify(obj));
18  
19 //控制縮排,該引數的值可以是數字也可以是字串,自動換行
20 //001 如果是字串那麼會把對應的字元拼接在鍵值對前面,超過10個字元的省略
21 //002 如果是數字那麼會設定對應的縮排,最多為10,超過則預設為10
22 console.log(JSON.stringify(obj, null, 4));
23 console.log(JSON.stringify(obj, null, "@@"));
24  
25 //過濾器(陣列):表示只處理key為name和age這兩個鍵值對
26 console.log(JSON.stringify(obj, ["name","age"]));
27  
28 //過濾器(函式):
29 function fn(key,value) {
30 if (key === "age")
31 {
32 return value + 20;
33 }else if (key === "name")
34 {
35 return undefined; //過濾掉key為name這個鍵值對
36 }else
37 {
38 return value;
39 }
40 }
41 console.log(JSON.stringify(obj,fn));

JSON資料總結

JSON全稱是JavaScript Object Notation基於JavaScript,是JavaScript的子集。
JSON雖然是JavaScript的子集,但並不從屬於JavaScript,它獨立於語言。
JSON是用來表示和傳輸資料的格式,比XML更輕量級,現已成為web資料交換的事實標準。
JSON的優勢在於其可以方便的把JSON字串資料轉換為對應的物件,比XML更方便且資料更小。
JSON語法可以表示:字串、數值、布林值、null、物件和陣列6種型別的值,不支援undefined。
JSON中的”鍵”區別於JavaScript,必須要加上雙引號。
JSON解析可以使用傳統的eval函式,或ECMAScript5推出的全域性物件來處理。

參考資料

JSON官網:http://json.org/
JSON維基百科:https://en.wikipedia.org/wiki/JSON
JSON作者簡介:https://en.wikipedia.org/wiki/Douglas_Crockford
JSON必知必會:https://book.douban.com/subject/26789960/
JavaScript高階程式設計:https://book.douban.com/subject/10546125/



相關文章