JSON(JavaScript Object Notation,JavaScript對象表示法)是JavaScript的一個嚴格的子集,利用了JavaScript中的一些模式來表示結構化數據。
JSON是一種數據格式,不是一種編程語言,雖然具備相同的語法格式,但JSON並不從屬於JavaScript,也並不僅有JavaScript才使用JSON,不少編程語言都有針對JSON的解析器和序列化器。編程
JSON的語法能夠表示三種類型的值:簡單值、對象和數組。json
最簡單的JSON數據形式就是簡單值,如:
JSON表示數值7的方式:數組
7
JSON表示字符串的方式:數據結構
"Hello Miyang!"
JavaScript字符串與JSON字符串最大的區別在於,JSON字符串必須使用雙引號。
布爾值和null也是有效的JSON形式。編程語言
咱們來對比一下JSON中的對象和JavaScript字面量:
JavaScript字面量:函數
var person = { name: "Miyang", age: 21 };
或this
var person = { "name": "Miyang", "age": 21 };
在JSON中的對象要求必須給屬性加引號:設計
{ "name": "Miyang", "age": 21 }
相比二者,JSON沒有聲明變量,其次,末尾也沒有分號,最重要的一點,對象的屬性必須加雙引號。
在實際使用中,咱們常常會遇到這樣的JSON數據:code
{ "name": "Miyang", "age": 21, "location": { "name": "Ping guo yuan", "city": "Beijing" } }
雖然該JSON中存在兩個name屬性,但因爲它們分別屬於不一樣的對象,所以沒有問題。同一個對象中絕對不該該出現兩個同名屬性。對象
在JSON中,能夠採用與JavaScript相同的語法表示一個數組:
["Miyang", 21, true]
一樣的,JSON數組也沒有變量和分號,數組和對象結合起來,能夠構成較爲複雜的數據集合。
[ { "name": "Miyang", "age": 21, "hobby": ["HTML", "CSS", "Javascript"] }, { "name": "Miyang", "age": 21, "hobby": ["HTML", "CSS", "Javascript"] }, { "name": "Miyang", "age": 21, "hobby": ["HTML", "CSS", "Javascript"] } ]
JSON的流行,更重要的緣由是能夠把JSON數據結構解析爲有用的JavaScript對象,相對於XML數據結構來講優點極爲明顯。如咱們能夠經過如下方法來獲取某個屬性:
person[0].name
早期JSON解析器基本經過JavaScript的eval()
函數,可是存在風險,由於可能會執行一些惡意代碼。從ECMAScript5開始,定義了全局對象JSON,能夠更方便的對JSON進行解析與序列化。
該方法能夠將JavaScript對象序列化爲一個JSON字符串,默認狀況下,輸出的字符串不包含任何空格字符或縮進,如:
var json = { "name": "Miyang", "age": 21 }; console.log(JSON.stringify(json)); // 輸出結果 {"name":"Miyang","age":21}
在序列化JavaScript對象時,全部函數即原型成員都會被有意忽略,不體如今結果中,值爲undefined的任何屬性也會被跳過,如:
var json = { "name": "Miyang", "age": 21, "test": undefined }; console.log(JSON.stringify(json)); // 輸出結果 {"name":"Miyang","age":21}
該方法能夠將JSON字符串轉換爲JSON對象,如:
var jsonTest = '{"name": "Miyang","age": 21,"test": "undefined"}'; console.log(JSON.parse(jsonTest)); // 輸出結果 { name: 'Miyang', age: 21, test: 'undefined' }
若是傳給JSON.parse()的字符串不是有效的JSON,該方法會拋出錯誤。
JSON.stringfiy()
還能夠接受兩個參數,用於指定以不一樣方式序列化JavaScript對象。
第一個參數是過濾器,能夠是一個數組,也能夠是一個函數。
第二個參數是一個選項,表示是否在JSON字符串中保留縮進。
若是過濾器參數是數組,那麼返回的結果就只包含數組中列出的屬性,如:
var json = { "name": "Miyang", "age": 21 }; console.log(JSON.stringify(json, ["name"])); // 輸出結果 {"name":"Miyang"}
若是過濾器參數是函數,則該函數能夠接收兩個參數,屬性名和屬性值,隨後根據函數對結果進行過濾,如:
var json = { "name": "Miyang", "age": 21, "hobby": ["HTML", "CSS"] }; console.log(JSON.stringify(json, function(key, value) { switch(key) { case "name": return value + "!!!"; case "age": return 18; case "hobby": return undefined; default: return value; } })); // 輸出結果 {"name":"Miyang!!!","age":18}
這裏注意,若是函數返回了undefined,那麼相應的屬性會被忽略。
JSON.stringify()
的第三個方法用於控制結果中的縮進和空白符,若是該參數是一個數值,則表示每一個縮進的空格數,最大縮進爲10,大於10的值會自動轉換爲10。當傳入了有效縮進參數值,結果字符串就會包含換行符。
var json = { "name": "Miyang", "age": 21, "hobby": ["HTML", "CSS"] }; console.log(JSON.stringify(json, null, 2)); // 輸出結果 { "name": "Miyang", "age": 21, "hobby": [ "HTML", "CSS" ] }
若是縮進參數是一個字符串,則這個字符串將在JSON字符串在做爲縮進字符,一樣的,長度不能超過10個字符長,不然只顯示前10個字符。
var json = { "name": "Miyang", "age": 21, "hobby": ["HTML", "CSS"] }; console.log(JSON.stringify(json, null, '-')); // 輸出結果 { -"name": "Miyang", -"age": 21, -"hobby": [ --"HTML", --"CSS" -] }
當JSON.stringify()
不能知足需求時,能夠給對象定義toJSON()
方法,返回其自身的JSON數據格式。
var json = { "name": "Miyang", "age": 21, "address": { "city": "Beijing" }, toJSON: function() { return this.name; } }; console.log(JSON.stringify(json)); // 輸出結果 "Miyang"
可讓這個方法返回undefined,若是此時包含它的對象嵌入在另外一個對象中,會致使它的值變成null,若是是頂級對象,則返回undefined。
var json = { "name": "Miyang", "age": 21, "address": { "city": "Beijing" }, toJSON: function() { return undefined; } }; console.log(JSON.stringify(json)); // 輸出結果 undefined
var json = { "name": "Miyang", "age": 21, "address": { "city": "Beijing", toJSON: function() { return undefined; } } }; console.log(JSON.stringify(json)); // 輸出結果 {"name":"Miyang","age":21}
咱們須要瞭解一下序列化內部工做順序,假設把一個對象傳入JSON.stringify()
,序列化該對象的順序以下:
toJSON()
方法並且能取得有效值,則調用該方法,不然返回對象自己。JSON.parse()
也能夠接收另外一個參數,該參數是一個函數,對每一個鍵值對進行調用,被稱之爲還原函數。一樣的,它接收兩個參數,一個鍵和一個值,且須要返回一個值。
若是返回undefined,則表示要從結果中刪除相應的鍵,若是返回其餘值,則將該值插入到結果中,在將日期字符串轉換爲Date對象時,常常用到還原函數。
var json = { "name": "Miyang", "age": 21, "address": { "city": "Beijing" }, "date": new Date(2011, 11, 1) }; var jsonText = JSON.stringify(json); var jsonCopy = JSON.parse(jsonText, function(key, value) { if(key === "date") { return new Date(value); }else { return value; } }); console.log(jsonCopy.date.getTime()); // 輸出結果 1322668800000
JSON是一個輕量級的數據格式,能夠簡化表示複雜數據結構的工做量,瞭解其結構、掌握JavaScript對其的操做方法,能夠更便捷的進行先後臺交互或數據處理。
參考資料:JavaScript高級程序設計(第三版)第20章