JSON(JavaScript Object Notation)
是一種輕量級的數據交換格式。易於人閱讀和編寫。同時也易於機器解析和生成。它基於JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999
的一個子集。
JSON
指的是 JavaScript 對象表示法(JavaScript Object Notation
)JSON
是輕量級的文本數據交換格式JSON
獨立於語言:JSON 使用 Javascript
語法來描述數據對象,可是 JSON 仍然獨立於語言和平臺。JSON 解析器和 JSON 庫支持許多不一樣的編程語言。 目前很是多的動態(PHP,JSP,.NET
)編程語言都支持JSON。JSON
具備自我描述性,更易理解JSON
大體3種結構,JSON
對象、JSON
數組和JSON
對象和數組嵌套。javascript
Object
是一個無序‘名稱/值’對
集合,一個對象以{
(左括號)開始,}
(右括號)結束。每一個名稱
後跟一個:
(冒號);‘名稱/值’ 對
之間使用,
(逗號)分隔。java
其中鍵值對中的鍵必須是string
類型,值能夠是json三種Object|Array|value
類型中的一種,string
屬於一種value
,value
包含string、null、number
等,後面第三種會講
實例:git
{} {"aa": true} {"bb": "3333"} {"cc": null} {"dd": {"ee": ["ff","gg"]}}
數組是值(value)的有序集合。一個數組以[
(左中括號)開始,]
(右中括號)結束。值之間使用,
(逗號)分隔。github
示例:編程
[] ["aa","bb"] [[1,2],[3,4]] [{"aa": []},{bb: []}]
值(value)
能夠是雙引號括起來的字符串(string)、數值(number)、true、false、 null、對象(object)或者數組(array)
。這些結構能夠嵌套。json
string
是value
中比較特殊的須要注意的一種;字符串(string)是由雙引號包圍的任意數量Unicode字符的集合,使用反斜線轉義。一個字符(character)即一個單獨的字符串(character string)。數組
示例:編程語言
"aaa" "\ttab" "\nnew line"
看起來很簡單啊;結果咱們去V8環境中運行了一下,函數
JSON.parse("\nnewline"); VM5802:2 Uncaught SyntaxError: Unexpected token e in JSON at position 2 at JSON.parse (<anonymous>) at <anonymous>:1:6 (anonymous) @ VM5801:1 JSON.parse("\ttab"); VM5836:1 Uncaught SyntaxError: Unexpected token a in JSON at position 2 at JSON.parse (<anonymous>) at <anonymous>:1:6
藍瘦了,不是說好的格式嗎?反向測試:測試
JSON.stringify('2 2') ""2\t2"" JSON.parse(JSON.stringify('2 2')) "2 2" JSON.stringify('2 2') ""2\t2"" JSON.parse('"2\t2"') VM330:1 Uncaught SyntaxError: Unexpected number in JSON at position 2 at JSON.parse (<anonymous>) at <anonymous>:1:6
問題好像有點眉頭了,爲何直接使用字符串的時候會有問題呢?是否是js的字符串定義和解析的鍋?MDN上的js的string
轉義字符節 除了普通的可打印字符之外,一些特殊有特殊功能的字符能夠經過轉義字符的形式放入字符串中: Code Output \0 空字符 \' 單引號 \" 雙引號 \\ 反斜槓 \n 換行 \r 回車 \v 垂直製表符 \t 水平製表符 \b 退格 \f 換頁 \uXXXX unicode 碼 \u{X} ... \u{XXXXXX} unicode codepoint \xXX Latin-1 字符(x小寫)
問題的根本緣由在於使用V8的JSON.parse
的時候,參數會被V8先解析爲字符串;
'"\ttab"' => "" tab"" '"\nnewline"' => "" newline"" '"2\t2"' => ""2 2""
被解析後的字符串變了樣子,這些解析後的字符串再也不符合JSON的格式,因此解析就會報錯了。詳情參考:從一個 JSON.parse 錯誤深刻研究 JavaScript 的轉義字符
數值(number)也與C或者Java的數值很是類似。除去不曾使用的八進制與十六進制格式。除去一些編碼細節。
JSON對象包含兩個方法: 用於解析 JavaScript Object Notation (JSON) 的 parse() 方法,以及將對象/值轉換爲 JSON字符串的 stringify() 方法。除了這兩個方法, JSON這個對象自己並無其餘做用,也不能被調用或者做爲構造函數調用。
JSON.parse()
方法用來解析JSON字符串,構造由字符串描述的JavaScript值或對象。提供可選的reviver函數用以在返回以前對所獲得的對象執行變換(操做)。parse語法介紹和使用mdn
JSON.parse(text[, reviver]) >若是指定了 reviver 函數,則解析出的 JavaScript 值(解析值)會通過一次轉換後纔將被最終返回(返回值)。更具體點講就是:解析值自己以及它所包含的全部屬性,會按照必定的順序(從最最裏層的屬性開始,一級級往外,最終到達頂層,也就是解析值自己)分別的去調用 reviver 函數,在調用過程當中,當前屬性所屬的對象會做爲 this 值,當前屬性名和屬性值會分別做爲第一個和第二個參數傳入 reviver 中。若是 reviver 返回 undefined,則當前屬性會從所屬對象中刪除,若是返回了其餘值,則返回的值會成爲當前屬性新的屬性值。 >當遍歷到最頂層的值(解析值)時,傳入 reviver 函數的參數會是空字符串 ""(由於此時已經沒有真正的屬性)和當前的解析值(有可能已經被修改過了),當前的 this 值會是 {"": 修改過的解析值},在編寫 reviver 函數時,要注意到這個特例。(這個函數的遍歷順序依照:從最內層開始,按照層級順序,依次向外遍歷)
JSON.stringify()
方法是將一個JavaScript值(對象或者數組)轉換爲一個 JSON字符串,若是指定了replacer是一個函數,則能夠替換值,或者若是指定了replacer是一個數組,可選的僅包括指定的屬性。mdn文檔
JSON.stringify(value[, replacer [, space]])
須要注意後面連個參數,replacer
能夠是函數或者數組;
做爲函數,它有兩個參數,鍵(key)值(value)都會被序列化。
若是返回一個 Number, 轉換成相應的字符串被添加入JSON字符串。
若是返回一個 String, 該字符串做爲屬性值被添加入JSON。
若是返回一個 Boolean, "true" 或者 "false"被做爲屬性值被添加入JSON字符串。
若是返回任何其餘對象,該對象遞歸地序列化成JSON字符串,對每一個屬性調用replacer方法。除非該對象是一個函數,這種狀況將不會被序列化成JSON字符串。
若是返回undefined,該屬性值不會在JSON字符串中輸出。
注意: 不能用replacer方法,從數組中移除值(values),如若返回undefined或者一個函數,將會被null取代。
space
參數用來控制結果字符串裏面的間距。若是是一個數字, 則在字符串化時每一級別會比上一級別縮進多這個數字值的空格(最多10個空格);若是是一個字符串,則每一級別會比上一級別多縮進用該字符串(或該字符串的前十個字符)。
最近發現一個庫fast-json-stringify,由於他的介紹很簡潔:2x faster than JSON.stringify()
;須要一探究竟。