已經(jīng)有九天沒有發(fā)表文章更新了烹吵,嚴(yán)重違反了自己定好的“每周至少發(fā)表一篇文章”的計劃。因?yàn)槭窃谔α俗雅常磐砭诺模袝r下班回家就直接睡覺(感覺給自己找了些許借口==||
)氛魁。好了暮顺,廢話不多說了厅篓,來看正文。
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 function
var evalJson = eval('(' + jsonstr + ')');
//json.parse function
var jsonParseJson = JSON.parse(evalJson);
4. JSON.parse() 和 eval()的區(qū)別
在代碼中使用eval()是非常危險的,因?yàn)閑val()在解析字符串時撩鹿,會執(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); //控制臺下會報錯并顯示堆棧信息
var jsonObj4 = eval('('+errJson+')'); //控制臺下不會報錯,jsonObj4 = undefined
5. 談?wù)凧avascript在解析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,則報錯了阁危,原因是Javascript把'1'看成數(shù)字了捆姜,數(shù)字沒有split這個方法
//解決方式:
//將value強(qiáng)制轉(zhuǎn)化為字符串
var str = new String(value); //這樣對于json1的數(shù)據(jù)就不會報錯了
所以锌俱,對于JSON,我覺得格式統(tǒng)一很重要永脓,并且為其value全部加上引號袍辞,這樣規(guī)范后,可以讓前端少踩一些不必要的坑常摧。
{"鍵名稱有引號":"鍵值也有引號"}
{"key":"value"}
{"tag":"1"}
//不推薦這種:
{"tag":1}
文章更新日志:
2016-07-17 19:01 《談?wù)凧SON那些事》初稿