也許很多人還沒有接觸過JSON,為了梳理自己的知識,也為了方便想自學(xué)JSON的人學(xué)習(xí),我這里給大家寫了一篇JSON基礎(chǔ)教程。
1. 什么是JSON?
什么是JSON?記得剛開始接觸JSON這一概念的時候是在大三的時候,由于需要將數(shù)據(jù)從WEB服務(wù)器后臺傳遞到頁面中,比如,需要將一個名為name的屬性值傳遞到頁面,當(dāng)然,這很平常、很簡單??墒?,如果我要傳遞很多數(shù)據(jù),很多有組織性的數(shù)據(jù),比如是一個實(shí)體類的數(shù)據(jù),或者說是數(shù)據(jù)庫中的一條記錄,那要如何傳遞到前端頁面呢?其實(shí),在絕大所數(shù)的異步請求下,都會使用JSON這種數(shù)據(jù)格式來實(shí)現(xiàn),對于一些比較單一的數(shù)據(jù)則可以采用框架自帶的功能或者使用像EL/ONGL等類似的標(biāo)記性語言。當(dāng)然,這里還是強(qiáng)調(diào)一下JSON這種數(shù)據(jù)格式。
JSON(Javascript Object Notation)是一種輕量級的數(shù)據(jù)格式,完全獨(dú)立于語言的文本格式,也就是說整個JSON文檔就是一個文本文檔,所以JSON是一種理想的數(shù)據(jù)交換格式。在非關(guān)系型數(shù)據(jù)庫中,也能見到JSON的身影,比如在MongoDB中,也采用了一種類似JSON的數(shù)據(jù)格式,不過它叫BSON。JSON在Javascript中處理是不需要額外的API或者工具包的,所以效率非常高。
2. JSON數(shù)據(jù)格式
記住,JSON不是一種語言,只是一種數(shù)據(jù)格式。這種格式在存儲的時候最多算是一個字符串?dāng)?shù)據(jù)而已。
下面簡要介紹一下JSON的數(shù)據(jù)格式規(guī)范
demo1 = {} //空數(shù)據(jù)
demo2 = {"key":"value"} //JSON是一種鍵值對的集合格式,每個鍵對應(yīng)一個值
demo3 = {"key":[1,2,3]} //JSON中可以存儲數(shù)組元素
demo4 = { //JSON中可以存儲無限個鍵值對數(shù)據(jù)
"key1":"value1",
"key2","value2"
}
demo5 = { //理論上,JSON可以進(jìn)行無限次的嵌套
"key1":"value1",
"key2":{
"key3":"value3",
"key4":"value4"
}
}
3. JSON在Javascript中的解析方法
在Javascript中,主要采用以下兩個方法來解析JSON數(shù)據(jù):
eval() 和 JSON.parse()
基本的使用方式如下:
var jsonstr = '{"name":"jifeng","company":"taobao"}';
//eval functionvar evalJson = eval('(' + jsonstr + ')');
//json.parse functionvar jsonParseJson = JSON.parse(evalJson);
4. JSON.parse() 和 eval()的區(qū)別
在代碼中使用eval()是非常危險的,因?yàn)?/span>eval()在解析字符串時,會執(zhí)行該字符串中的代碼,特別是用它執(zhí)行第三方JSON字符串時,可能包含有惡意代碼。而JSON.parse()方法解析字符串本身。使用JSON.parse()可以捕捉JSON中的語法錯誤。
var jsonStr = {"key":"demo","key2":"demo"};
var jsonObj1 = JSON.parse(jsonStr); //使用JSON.parse()解析JSON,不會執(zhí)行jsonStr中的代碼var jsonObj2 = eval('('+jsonStr+')'); //會執(zhí)行jsonStr中的代碼,非常不安全
var errJson = {'error json format example'} //這是一段錯誤的JSON格式的數(shù)據(jù)
var jsonObj3 = JSON.parse(errJson); //控制臺下會報(bào)錯并顯示堆棧信息var jsonObj4 = eval('('+errJson+')'); //控制臺下不會報(bào)錯,jsonObj4 = undefined
5. 談?wù)?/span>Javascript在解析JSON時存在的坑
1 轉(zhuǎn)義字符:數(shù)據(jù)本身存在需要使用轉(zhuǎn)義字符才能表示的字符
在Javascript中,有一個轉(zhuǎn)義字符就是\,可以說對于沒有深入接觸過JSON的新手來說,很大概率上會踩這個坑。比如你的JSON數(shù)據(jù)是這個樣子的:
{"key1":"\"demo\""}
就這個格式的數(shù)據(jù),在服務(wù)端程序中表示的時候是沒有問題的,數(shù)據(jù)本身就帶有雙引號,所以這里使用到了轉(zhuǎn)義字符\,但是在Javascript中就不行了,Javascript是不允許出現(xiàn)任何轉(zhuǎn)義字符的。那如果真的要存儲需要轉(zhuǎn)義字符才能實(shí)現(xiàn)的數(shù)據(jù)時,比如數(shù)據(jù)本身就帶有雙引號,那么這個時候真么解決呢?我想一個比較土的方法就是先替換掉JSON字符串中的所有需要使用轉(zhuǎn)義字符表示的字符,然后再進(jìn)行解析,解析完成后再將原來的字符替換回去。
var demo = "{"key":"value\""}"; //帶有雙引號的JSON數(shù)據(jù)
var dealDemo = demo.replace('\\','-'); //將數(shù)據(jù)中的'\'轉(zhuǎn)化為'-'
var jsonDemo = JSON.parse(dealDemo); //解析JSON數(shù)據(jù)
var data = jsonDemo.key.replace('-','\\'); //將雙引號替換回去
當(dāng)然,這種辦法也不是有弊端的,那就是你的json數(shù)據(jù)本身不能出現(xiàn)-這個字符。
2 數(shù)字&字符串
這個問題我也是最近才發(fā)現(xiàn)的(筆者也是踩坑過來的=.=)。先來看個簡單的例子:
//假設(shè)某類型的數(shù)據(jù)有不同的值,可以單個值,也可以多個值,多個值是使用逗號隔開var json1 = {"key":"tag","key1":1} ;var json2 = {"key":"tag","key1
![257251_1455763624_2481.png](http://upload-images.jianshu.io/upload_images/1784374-bfb508453e93788b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
":"1,2"}
//遍歷JSON數(shù)據(jù)集合,同時解析其value值,將其分開var demo = JSON.parse(json1);var value = demo.tag;var values = value.split(',');
//對于json2,是正常的,得到的values = [1,2]//對于json1,則報(bào)錯了,原因是Javascript把'1'看成數(shù)字了,數(shù)字沒有split這個方法
//解決方式://將value強(qiáng)制轉(zhuǎn)化為字符串var str = new String(value); //這樣對于json1的數(shù)據(jù)就不會報(bào)錯了
所以,對于JSON,我覺得格式統(tǒng)一很重要,并且為其value全部加上引號,這樣規(guī)范后,可以讓前端少踩一些不必要的坑。
{"鍵名稱有引號":"鍵值也有引號"}
{"key":"value"}
{"tag":"1"}
//不推薦這種:
{"tag":1}
原文來自:簡書/翹著二郎腿打代碼