你了解JSON嘛?JSON是JavaScript中對象嘛?JSON可以存儲function對象嘛?JSON的本質(zhì)是什么呢?JSON能寫(xiě)注釋嘛?
如果你都能答上來(lái),那恭喜你,你對JSON了解的很測底,如果你有寫(xiě)不太明白,哪有必要和我一起來(lái)探討JSON。
我之前對JSON的概念也是一知半解,常常和JavaScript的Object對象混淆,所以就導致了很多種種的錯誤,特別是在研究NodeJS中,有一個(gè)叫package.json的文件專(zhuān)門(mén)用來(lái)存儲json格式的數據。如果你在這個(gè)文件里面寫(xiě)注釋?zhuān)蛘叽鎯瘮?,最終解析這個(gè)文件時(shí)就會(huì )報錯。
然后自己查閱了些相關(guān)的資料,得出些結論?,F在拿出來(lái)和大家分享一下,同時(shí),假如文章中有紕漏的地方,大家可以幫我指點(diǎn)糾正下。
首先我們來(lái)看看官方是怎么描述JSON的:JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。 易于人閱讀和編寫(xiě)。同時(shí)也易于機器解析和生成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一個(gè)子集。 JSON采用完全獨立于語(yǔ)言的文本格式,但是也使用了類(lèi)似于C語(yǔ)言家族的習慣(包括C, C++, C#, Java, JavaScript, Perl, Python等)。 這些特性使JSON成為理想的數據交換語(yǔ)言。參考來(lái)源地址:http://www.json.org/json-zh.html。
官方的說(shuō)法,也不是特別的明了,只說(shuō)明了這是一種輕量級的數據交換格式,且基于JavaScript一個(gè)子集。這根本說(shuō)明不了什么?不過(guò)我聯(lián)想到了另外一種數據交換格式,那就是xml,這個(gè)格式特別在webService中被大量使用。xml是什么呢,其本質(zhì)是一種DOM結構。對比一下,那json的本質(zhì)就是字符串了,不過(guò)這個(gè)字符串不是不同的字符串,它有一些列的語(yǔ)法和結構。下面我們就介紹下其語(yǔ)法。
常見(jiàn)JSON數據結構有兩種形式,其分別是:
首先來(lái)看第一種情況:對象是一個(gè)無(wú)序的“‘名稱(chēng)/值’對”集合。一個(gè)對象以“{”(左括號)開(kāi)始,“}”(右括號)結束。每個(gè)“名稱(chēng)”后跟一個(gè)“:”(冒號);“‘名稱(chēng)/值’ 對”之間使用“,”(逗號)分隔。
這和JavaScript中的對象字面量比較類(lèi)似,但是本質(zhì)上還是有些區別的。比如對象中的名稱(chēng)(或者稱(chēng)為key)是必須用雙引號括起來(lái)的。單引號都不行,更別說(shuō)忽略它了,雖然JavaScript中的對象中的名稱(chēng)值常常忽略雙引號。比如
{ name : 'test', age : 123, success : function(){ //todo }}則在JSON中是行不通的。除了"名稱(chēng)(key)"值有限制外,對象中的"值(value)"也做了限制,比如在JavaScript中的對象字面量中的值可以隨便賦值,不管是字符串、數組、函數、整形都是可以的。JSON中的取值可以是雙引號括起來(lái)的字符串(string)、數值(number)、true、false、 null、對象(object)或者數組(array),
除此之外,這些值以外都會(huì )被解析出問(wèn)題,像剛才頭中提到的,如果給JSON的值賦值一個(gè)function是一個(gè)錯誤的行為。
接下來(lái),看看值的有序列表(或者稱(chēng)為數組),數組是值的有序列表,一個(gè)數組以“[”(左中括號)開(kāi)始,“]”(右中括號)結束。值之間使用“,”(逗號)分隔,并且值的限制情況在上面中已經(jīng)提到。
差不多把語(yǔ)法介紹完了,總結一下,JSON其本質(zhì)是一串有意義的字符串數據交互格式。呵呵,不知道我定義的正不正確。
在JavaScript中經(jīng)常是要對JSON進(jìn)行處理的,比如提交一個(gè)數據前常常需要對其進(jìn)行序列化處理,從后來(lái)拉過(guò)來(lái)的JSON數據,我們經(jīng)常要對它進(jìn)行解析然后得到一個(gè)JavaScript對象??赡苡捎诖蠹医?jīng)常使用一些JavaScript類(lèi)庫,這些庫對JSON的操作做了封裝,所以造成一種現象,那就是我們只會(huì )用,對齊本質(zhì),我們了解甚少?,F在我們就拋開(kāi)類(lèi)庫,了解其底層的本質(zhì)。
早期的JSON解析器通過(guò)JavaScript中eval()函數來(lái)解析的。直到ECMA5對齊進(jìn)行了規范,并且定義了一個(gè)全局的JSON對象用來(lái)對JSON進(jìn)行解析和序列化。支持JSON這個(gè)全局對象的瀏覽器包括IE8+、FF3.5+、Safari4+、Chrome和Opera10.5+。對于不支持這個(gè)對象的瀏覽器比如IE6、IE7怎么做處理呢?
不用擔心,JSON的發(fā)明者早就幫我們實(shí)現了兼容的代碼,其地址為:https://github.com/douglascrockford/JSON-js。對于不支持原生的JSON對象的。我們可以引入這段代碼解決兼容性的問(wèn)題。
JSON有兩個(gè)主要方法,用來(lái)解決JSON的序列化和解析,其分別是stringfy和parse.讓我們分別來(lái)看看它們的用法。
ECMA5定義的標準接口如下所示:
/**@param {*} value@param {Function} [replacer]@param {Number|String} [space]@static*/JSON.stringify = function(value,replacer,space) {};其中對一個(gè)參數是必須滴,而且是我們要進(jìn)行序列化的對象。示例代碼如下所示:
var obj = { name : 'hello', age : 18}var jsonText = JSON.stringify(obj) //輸出:{"name":"hello","age":18}第二個(gè)參數是可選項,可以是函數或者是數組。如果是數組,那么數組中指定是過(guò)濾項,以上面例子為例,進(jìn)行如下調用:
var jsonText = JSON.stringify(obj,["name"]) //輸出: {"name":"hello"}如果是函數的話(huà),回調函數里面的參數對應Javascript中對象里面的key和value值。示例如下:
var jsonText = JSON.stringify(obj,function(key,value){ switch(key) { case "name": return value+" json"; case "age" : return 20; default : return value; }});//輸出 {"name":"hello json","age":20}第三個(gè)參數也是可選的。用來(lái)進(jìn)行字符串縮進(jìn),示例如下:
var jsonText = JSON.stringify(obj,null,4); //按4個(gè)空格縮進(jìn)//輸出的結果不再是單行,而是下面的形式:{ "name" : "hello", "age" : 18}除了可以設置數字外,還可以用字符設置縮進(jìn),有興趣大家可以嘗試一下。
ECMA5對parse接口的定義如下:
/**@param {string} jsonString@param {Function} [reviver]@static*/JSON.parse = function(jsonString,reviver) {};該方法接受兩個(gè)參數,其中第二個(gè)參數是可選的。
第一個(gè)參數的作用是待轉換的JSON字符串。比如我們可以將上面的jsonText通過(guò)parse還原成原來(lái)的Javascript對象。
var obj = JSON.parse(jsonText); //obj為JavaScript對象。
第二個(gè)參數是一個(gè)函數,用來(lái)更加細微的控制轉換過(guò)程。它接受兩個(gè)參數,分別對應著(zhù)JSON數據的鍵值對。調用示例如下:
var obj = JSON.parse(jsonText,function(key,value){ //todo }); JSON中文官網(wǎng)
聯(lián)系客服