JSON(JavaScript Object Notation)
,指JavaScript
的對象表示法,它自己是個字符串,是一種數據交換格式,並不是對象。一般所提的JSON
對象實際是JSON
字符串解析成對象的結果,或是瀏覽器window
對象下的JSON
對象。javascript
並且JSON
不止用於JavaScript
中,其普遍用於數據交換。html
一個JSON
文件,或一段JSON
字符串,一般是這樣的:java
[{ "name": "用戶權限管理", "code": "99990002", "icon": "modicon-1", "items": [{ "name": "模塊權限", "code": "999900020009", "url": "", "isBlank": false, "items": [{ "name": "嚮導模板", "code": "9999000200090003", "url": "pages/accLayoutTest.html", "isBlank": false, "items": [] }, { "name": "模塊管理咱們的", "code": "9999000200090001", "url": "pages/contentPageTest.html", "isBlank": false, "items": [] }] }] }, ... ]
而這樣相似的JavaScript
對象則是這樣的:git
var menuData = [{ name: "用戶權限管理", code: "99990002", icon: "modicon-1", items: [{ name: "模塊權限", code: "999900020009", url: "", isBlank: false, items: [{ name: "嚮導模板", code: "9999000200090003", url: "pages/accLayoutTest.html", isBlank: false, items: [] }, { name: "模塊管理咱們的", code: "9999000200090001", url: "pages/contentPageTest.html", isBlank: false, items: [] }] }] }, ...]
二者很是的類似,所不一樣的是就是JavaScript
對象中屬性名,也就是對象的key
值是能夠沒有引號的,其值爲字符串時,使用''
和""
包裹都可。 所以咱們不少人將第一段代碼塊裏所寫的JSON
稱爲JSON對象,實際上,它並非一個對象,只是一個單純的字符串而已,可是它符合JSON
的語法規則,能夠很方便地轉化爲JavaScript
對象,或者方便地用於數據交換。github
如下咱們來了解一下JSON
。ajax
JSON語法規則正則表達式
JSON 語法是 JavaScript 對象表示語法的子集,其基本原則以下:json
數據在鍵值對中數組
數據由逗號分隔瀏覽器
花括號保存對象
方括號保存數組
JSON的值
數字(整數或浮點數)
字符串(在雙引號中)
邏輯值(true
或 false
)
數組(在方括號中[]
)
對象(在花括號中{}
)
null
JSON
做爲一種數據交換格式,爲了保證其能被正確方便的解析,其格式有嚴格的要求,必須遵循如下規則:
複合類型的值只能是數組或對象,不能是函數、正則表達式對象、日期對象。
簡單類型的值只有四種:字符串、數值(必須以十進制表示)、布爾值和null
(不能使用NaN
, Infinity
, -Infinity
和undefined
)。
字符串必須使用雙引號表示,不能使用單引號。
對象的鍵名必須放在雙引號裏面。
數組或對象最後一個成員的後面,不能有逗號。
數值前不能加0。
如下是合法的JSON
格式示例:
["one", "two", "three"] { "one": 1, "two": 2, "three": 3 } { "names": [ "張三", "李四" ] } [ { "name": "張三" }, { "name": "李四" } ]
下面這些就是不合法的:
{ name: "張三", 'age': 32 } // 屬性名必須使用雙引號 [32, 64, 128, 0xFFF] // 不能使用十六進制值 { "name": "張三", "age": undefined } // 不能使用undefined { "name": "張三", "birthday": new Date('Fri, 26 Aug 2011 07:13:10 GMT'), "getName": function() { return this.name; } } // 不能使用函數和日期對象 { "name": "李四", "age": 018 } // 數值前不能有0
以上代碼中爲了指出錯誤所在,使用了
JavaScript
的註釋法,實際JSON
中是不能有註釋的。不合法的
JSON
會在解析成JavaScript
對象時,出現錯誤。
JSON
做爲一種數據交換格式,被寫入了ECMAScript 5,在IE8及以後的瀏覽器都提供了一個JSON
對象,用於對JSON
進行解析和序列化。
此方法接收一個JSON
字符串,返回解析後的JavaScript對象,一般爲Object
或Array
。
// JSON數據 var humansData = '[{"name":"zs","age":28},{"name":"ls","age":26}]'; // 解析爲JavaScript對象 var humans = JSON.parse(humansData); // 以後就能夠訪問其元素或屬性了 humans[1].name; // ls humans[1].age; // 26
若是傳入不合法的
JSON
,則會在JSON.parse
時報錯。
爲何咱們在ajax請求中,即便請求的數據爲JSON
,咱們不用解析就能直接使用呢?
// test.text內容 /* [{ "name":"zs", "age":28 },{ "name":"ls", "age":26 }] */ $.ajax({ url: './test/test.text', dataType: 'JSON' }).done(function(data){ console.dir(data); // Array[2] console.log(data[0].name); // zs // 這裏沒有轉化爲js對象就能訪問其屬性?! });
這裏實際是由於指定了dataType
爲JSON,從而進行了自動轉化,因此能直接在成功回調中使用其屬性。若是去掉dataType
的指定,就不能直接訪問其屬性了,由於未轉化時,其自己是一個字符串。第一行輸出爲test.text的內容,第二行輸出undefined
。
此方法可接收一個JavaScript
值將轉化爲JSON
字符串,此字符串可被JSON.parse
還原。
var humans = [{ "name": "zs", "age": 28, "birth": new Date() }, { "name": "ls", "age": 26, "birth": new Date() }]; // 轉化爲JSON字符串 JSON.stringify(humans); // "[{"name":"zs","age":28,"birth":"2016-10-25T07:24:11.701Z"},{"name":"ls","age":26,"birth":"2016-10-25T07:24:11.701Z"}]"
前面咱們講到了JSON
中並不是支持全部的JavaScript
類型,所以此方法對一些JSON
不可接受的值有所處理:原始對象中,若是有一個成員的值是undefined、函數或XML對象,這個成員會被省略。若是數組的成員是undefined、函數或XML對象,則這些值被轉成null。
咱們還發現,JSON
中是不支持Date
對象的,而上述轉化爲字符串的結果中正確包含了birth
的值,其爲一個日期格式的字符串。這是由於在Date
對象上有一個名爲toJSON
的方法,JSON.stringify
在序列化時,實際是調用了這個方法來輸出結果的。
若是一個被序列化的對象擁有 toJSON 方法,那麼該 toJSON 方法就會覆蓋該對象默認的序列化行爲:不是那個對象被序列化,而是調用 toJSON 方法後的返回值會被序列化,例如:
var obj = { foo: 'foo', toJSON: function() { return 'bar'; } }; JSON.stringify(obj); // '"bar"' JSON.stringify({x: obj}); // '{"x":"bar"}'
瞭解便可,詳見: MDN:JSON.stringify(){.doc-link}
咱們可能常常看到的是JSON.stringify( obj , null , 4)
,這樣是什麼意思呢?
對於上例,替換最後一句,結果以下所示:
JSON.stringify(humans, null, 4); // "[ // { // "name": "zs", // "age": 28, // "birth": "2016-10-25T07:24:11.701Z" // }, // { // "name": "ls", // "age": 26, // "birth": "2016-10-25T07:24:11.701Z" // } // ]"
其實沒什麼變化,不過是加上了空格縮進,使得可讀性更高了。
其他兩個參數的說明以下:
第二個參數可指定序列化時的操做。
若是該參數是一個函數,則在序列化過程當中,被序列化的值的每一個屬性都會通過該函數的轉換和處理;
若是該參數是一個數組,則只有包含在這個數組中的屬性名纔會被序列化到最終的 JSON 字符串中;
若是該參數爲null或者未提供,則對象全部的屬性都會被序列化;
第三個參數用於指定縮進用的空白字符串,用於美化輸出(pretty-print);
若是參數是個數字,它表明有多少的空格;上限爲10。該值若小於1,則意味着沒有空格;
若是該參數爲字符串(字符串的前十個字母),該字符串將被做爲空格;
若是該參數沒有提供(或者爲null)將沒有空格。
window.JSON
對象下雖然提供了完整的JSON
字符串和JavaScript
對象的轉換方法。可是在IE8(兼容模式)以及更低版本的IE下沒有提供這個對象,所以咱們須要一些替代方案。
jQuery中提供了parseJSON
這樣一個方法來替代JSON.parse
,它接收一個標準格式的JSON
字符串,返回一個解析後的JavaScript
對象。
使用http://www.json.org/提供了一個json.js,這樣ie8(兼容模式),ie7和ie6就能夠支持JSON對象以及其stringify()
和parse()
方法; 能夠在https://github.com/douglascrockford/JSON-js上獲取到這個js,通常如今用json2.js。
還可使用 eval('(' + jsonstr + ')')
; 來將json字符串轉換成json對象,注意須要在json字符外包裹一對小括號。但最好不要使用這種方式,由於這種方式不安全,eval
會將JSON
字符串做爲JavaScript
語句來執行,JSON
中的風險代碼將被執行。