javascript中json基礎知識詳解
大致介紹
JSON(JavaScript Object Notation JavaScript對象表示法),JSON是一種數(shù)據(jù)格式,不是一種編程語言。雖然它的名字中有JavaScript但是它卻不屬于JavaScript,就像Java和JavaScript的關系一樣。而且,并不是只有JavaScript才使用它,畢竟 JSON 只是一種數(shù)據(jù)格式。很多編程語言都有針對 JSON 的解析器和序列化器。
JSON是由Douglas Crockford在2001年提出,為了取代XML
語法
JSON的語法可以包含三種類型的值:
◆ 簡單值
◆ 對象
◆ 數(shù)組
簡單值
簡單值:使用與 JavaScript 相同的語法,可以在 JSON 中表示字符串、數(shù)值、布爾值和 null
注意:【1】JSON 不支持 JavaScript 中的特殊值 undefined
【2】JSON 字符串必須使用雙引號(單引號會導致語 法錯誤)
// 有效的JSON數(shù)據(jù) "Hellow World!" 5 true null
對象
對象作為一種復雜的數(shù)據(jù)類型,表示的是一組有序的鍵值對,每個鍵值對中的值既可以是簡單值也可以是復雜數(shù)據(jù)類型的值
JSON中的對象和JavaScript中的字面量稍微有一些不同:
1、沒有聲明變量
2、在末尾不需要加分號
3、JSON 中對象的屬性名任何時候都必須加雙引號
注意:同一個對象中絕對不應該出現(xiàn)兩個同名屬性
// JavaScript中的字面量 var person = { name : "Lao Wang", age : 21 }; // JSON { "name" : "Lao Wang", "age" : 21 } // 可以在對象中嵌入對象 { "name" : "Lao Wang", "age" : 21, "school" : { "name" : "TJLG", "location" : "西青" } }
數(shù)組
JSON 數(shù)組采用的就是 JavaScript 中的數(shù)組字面量形式
// JavaScript var values = [21,"西青",true]; // JSON values = [21,"西青",true]
JSON對象
早期的 JSON 解析器基本上就是使用 JavaScript 的 eval()函數(shù)。由于 JSON 是 JavaScript 語法的子 集,因此 eval()函數(shù)可以解析、解釋并返回 JavaScript 對象和數(shù)組,但是使用eval()函數(shù)對JSON數(shù)據(jù)結構求值存在風險,應為可能會執(zhí)行一些惡意代碼,所以要盡量少的使用eval()函數(shù)
ECMAScript 5 對解析 JSON 的行 為進行規(guī)范,定義了全局對象 JSON。支持這個對象的瀏覽器有 IE 8+、Firefox 3.5+、Safari 4+、Chrome 和 Opera 10.5+。對于較早版本的瀏覽器,可以使用一個 shim:https://github.com/douglascrockford/JSON-js。
JSON對象有兩個方法:
1、stringify()
2、parse()
stringify()
stringify()方法將JavaScript對象序列化為JSON字符串
注意:
【1】默認情況下,JSON.stringify()輸出的 JSON 字符串不包含任何空格字符或縮進
var person = { name : "Lao Wang", grade : { "English" : "88", "Math" : "98" } }; var jsonPerson = JSON.stringify(person); console.log(jsonPerson); // {"name":"Lao Wang","grade":{"English":"88","Math":"98"}}
【2】 如果對象的成員是undefined或者函數(shù),該成員會被忽略
如果數(shù)組的成員是undefined或者函數(shù),則這些值會被轉成null
var person = { name : function(){}, sex : undefined, age : 21, grade : [undefined,function(){},"English"], } var jsonPerson = JSON.stringify(person); console.log(jsonPerson); // {"age":21,"grade":[null,null,"English"]}
【3】JSON.stringify()會忽略對象的不可遍歷屬性
var person = {}; Object.defineProperties(person,{ 'name' : { value : "Lao Wang", enumerable : true }, 'age' : { value : 21, enumerable : false } }); var jsonPerson = JSON.stringify(person); console.log(jsonPerson); // {"name":"Lao Wang"}
實際上,JSON.stringify()除了要序列化的 JavaScript 對象外,還可以接收另外兩個參數(shù),這兩 個參數(shù)用于指定以不同的方式序列化 JavaScript 對象
第一個參數(shù)是個過濾器,可以是一個數(shù)組,也可 以是一個函數(shù)
第二個參數(shù)是一個選項,表示是否在 JSON 字符串中保留縮進
1、當?shù)谝粋€參數(shù)是數(shù)組時
如果過濾器參數(shù)是數(shù)組,那么 JSON.stringify()的結果中將只包含數(shù)組中列出的屬性
注意:
【1】、過濾器只對對象的第一層屬性有效
var person = { name : "Lao Wang", grade : { "English" : "88", "Math" : "98" } }; var jsonPerson = JSON.stringify(person,["name","Math"]); console.log(jsonPerson); // {"name":"Lao Wang"}
【2】過濾器對數(shù)組無效
var values = [21,"he",true,"we"]; var jsonValues = JSON.stringify(values,["he"]); console.log(jsonValues); // [21,"he",true,"we"]
2、當?shù)谝粋€參數(shù)是函數(shù)時
傳入的函數(shù)接收兩個參數(shù),屬性(鍵)名和屬性值。根據(jù)屬性(鍵)名可以知道應該如何處理要序列化的對象中的屬性。屬性名只能是字符串,而在值并非鍵值對兒結構的值時,鍵名可以是空字符串。 為了改變序列化對象的結果,函數(shù)返回的值就是相應鍵的值。
注意:如果函數(shù)返回了undefined或沒有返回值,那么相應的屬性會被忽略
var values = { name : "Lao Wang", age : 21, sex : "男" } var jsonValues = JSON.stringify(values,function(key,value){ if(key == "sex"){ return undefined; }else{ return value; } }); console.log(jsonValues); // {"name":"Lao Wang","age":21}
3、當給定第三個參數(shù)時
JSON.stringify()方法的第三個參數(shù)用于控制結果中的縮進和空白符。如果這個參數(shù)是一個數(shù)值,那它表示的是每個級別縮進的空格數(shù)
注意:
【1】只要傳入有效的控制縮進的參數(shù)值,結果字符串就會包含換行符
【2】最大縮進空格數(shù)為10,所有大于10的值都會自動轉換為10
【3】如果縮進參數(shù)是一個字符串而非數(shù)值,則這個字符串將在 JSON 字符串中被用作縮進字符(不再使用空格)
// 參數(shù)是數(shù)值 var person = { name : "Lao Wang", grade : { "English" : "88", "Math" : "98" } }; var jsonPerson = JSON.stringify(person,null,4); console.log(jsonPerson); /* { "name": "Lao Wang", "grade": { "English": "88", "Math": "98" } } */ // 參數(shù)是字符串 var person = { name : "Lao Wang", grade : { "English" : "88", "Math" : "98" } }; var jsonPerson = JSON.stringify(person,null,"-_-||"); console.log(jsonPerson); /* { -_-||"name": "Lao Wang", -_-||"grade": { -_-||-_-||"English": "88", -_-||-_-||"Math": "98" -_-||} } */
toJSON()
有時候,JSON.stringify()還是不能滿足對某些對象進行自定義序列化的需求。在這些情況下, 可以通過對象上調用toJSON()方法,返回其自身的JSON數(shù)據(jù)格式
var person = { name : "Lao Wang", grade : { "English" : "88", "Math" : "98" }, toJSON : function(){ return "toJSON方法"; } }; var jsonPerson = JSON.stringify(person); console.log(jsonPerson); // "toJSON方法"
注意:如果toJSON()方法返回undefined,此時如果包含它的對象嵌入在另一個對象中,會導致該對象的值變成null。而如果包含它的對象是頂級對象,結果就是undefined
// 嵌入在另一個對象中 var person = { name : "Lao Wang", grade : { "English" : "88", "Math" : "98" }, sex : { value : "男", toJSON : function(){ return undefined; } } }; var jsonPerson = JSON.stringify(person,null,4); console.log(jsonPerson); /* { "name": "Lao Wang", "grade": { "English": "88", "Math": "98" } } */ // 嵌入頂級對象 var person = { name : "Lao Wang", grade : { "English" : "88", "Math" : "98" }, toJSON : function(){ return undefined; } }; var jsonPerson = JSON.stringify(person,null,4); console.log(jsonPerson); // undefined
原生Date對象有一個toJSON()方法,能夠將JavaScript的Date 對象自動轉換成ISO 8601日期字符串(與在Date對象上調用toISOString() 的結果完全一樣)
var date = JSON.stringify(new Date("2017-1-18")); console.log(date); // "2017-01-17T16:00:00.000Z"
toJSON()可以作為函數(shù)過濾器的補充,因此理解序列化的內部順序十分重要。假設把一個對象傳入JSON.stringify(),序列化該對象的順序如下
1、如果存在toJSON()方法而且能通過它取得有效的值,則調用該方法。否則,按默認順序執(zhí)行序列化
2、如果提供了第二個參數(shù),應用這個函數(shù)過濾器。傳入函數(shù)過濾器的值是第一步返回的值
3、對第二步返回的每個值進行相應的序列化
4、如果提供了第三個參數(shù),執(zhí)行相應的格式化
JSON.parse()
JSON.parse()將JSON字符串解析為JavaScript值
var person = JSON.parse('{"name":"Lao Wang"}'); console.log(person.name); // Lao Wang
注意:如果傳入的字符串不是有效的JSON格式,JSON.parse方法將報錯
JSON.parse()方法也可以接收另一個參數(shù),該參數(shù)是一個函數(shù),將在每個鍵值對兒上調用。為了區(qū)別 JSON.stringify()接收的替換(過濾)函數(shù)(replacer),這個函數(shù)被稱為還原函數(shù)(reviver),還原函數(shù)接收兩個參數(shù),一個鍵和一個值,而且需要返回一個值
注意:如果還原函數(shù)返回 undefined,則表示要從結果中刪除相應的鍵;如果返回其他值,則將該值插入到結果中
var person = JSON.parse('{"name":"Lao Wang","age":21}',function(key,value){ if(key == "age"){ return undefined; }else{ return value; } }); console.log(person.name); // Lao Wang
在將日期字符串轉換為 Date 對象時,經(jīng)常要用到還原函數(shù)
var book = { "title": "Professional JavaScript", "authors": ["Nicholas C. Zakas"], edition: 3, year: 2011, releaseDate: new Date(2017, 1, 18) }; var jsonText = JSON.stringify(book,null,4); console.log(jsonText); /* { "title": "Professional JavaScript", "authors": [ "Nicholas C. Zakas" ], "edition": 3, "year": 2011, "releaseDate": "2017-02-17T16:00:00.000Z" } */ var bookCopy = JSON.parse(jsonText, function(key, value){ if (key == "releaseDate"){ return new Date(value); }else{ return value; } }); console.log(bookCopy.releaseDate.getFullYear()); // 2017
參考資料:
以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!
相關文章
JavaScript優(yōu)化以及前段開發(fā)小技巧
隨著前端技術的發(fā)展,前端業(yè)務越來越繁重,這大大增加了JS代碼量。因此,要提高Web的性能,我們不僅需要關注頁面加載的時間,還要注重在頁面上操作的響應速度。那么,接下來我們討論幾種能夠提高JavaScript效率的方法。2017-02-02js中substring和substr兩者區(qū)別和使用方法
這篇文章主要介紹了js中substring和substr兩者區(qū)別和使用方法,每一個步驟都有相應的文字介紹,感興趣的小伙伴們可以參考一下2015-11-11微信小程序基于高德地圖API實現(xiàn)天氣組件(動態(tài)效果)
這篇文章主要介紹了微信小程序基于高德地圖API實現(xiàn)天氣組件(動態(tài)效果),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10