JSON.stringify和fast-json-stringify的比較

JSON

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數據格式

JSON大體3種結構,JSON對象、JSON數組和JSON對象和數組嵌套。javascript

Object對象

Object是一個無序‘名稱/值’對集合,一個對象以{(左括號)開始,}(右括號)結束。每一個名稱後跟一個:(冒號);‘名稱/值’ 對之間使用,(逗號)分隔。java

clipboard.png
其中鍵值對中的鍵必須是string類型,值能夠是json三種Object|Array|value類型中的一種,string屬於一種valuevalue包含string、null、number等,後面第三種會講
實例:git

{}
{"aa": true}
{"bb": "3333"}
{"cc": null}
{"dd": {"ee": ["ff","gg"]}}

Array數組

數組是值(value)的有序集合。一個數組以[(左中括號)開始,](右中括號)結束。值之間使用,(逗號)分隔。github

clipboard.png

示例:編程

[]
["aa","bb"]
[[1,2],[3,4]]
[{"aa": []},{bb: []}]

值Value

(value)能夠是雙引號括起來的字符串(string)、數值(number)、true、false、 null、對象(object)或者數組(array)。這些結構能夠嵌套。json

clipboard.png

string

stringvalue中比較特殊的須要注意的一種;字符串(string)是由雙引號包圍的任意數量Unicode字符的集合,使用反斜線轉義。一個字符(character)即一個單獨的字符串(character string)。數組

clipboard.png

示例:編程語言

"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

數值(number)也與C或者Java的數值很是類似。除去不曾使用的八進制與十六進制格式。除去一些編碼細節。

clipboard.png

javascript的JSON對象

JSON對象包含兩個方法: 用於解析 JavaScript Object Notation (JSON) 的 parse() 方法,以及將對象/值轉換爲 JSON字符串的 stringify() 方法。除了這兩個方法, JSON這個對象自己並無其餘做用,也不能被調用或者做爲構造函數調用。

parse

JSON.parse() 方法用來解析JSON字符串,構造由字符串描述的JavaScript值或對象。提供可選的reviver函數用以在返回以前對所獲得的對象執行變換(操做)。parse語法介紹和使用mdn

JSON.parse(text[, reviver])
>若是指定了 reviver 函數,則解析出的 JavaScript 值(解析值)會通過一次轉換後纔將被最終返回(返回值)。更具體點講就是:解析值自己以及它所包含的全部屬性,會按照必定的順序(從最最裏層的屬性開始,一級級往外,最終到達頂層,也就是解析值自己)分別的去調用 reviver 函數,在調用過程當中,當前屬性所屬的對象會做爲 this 值,當前屬性名和屬性值會分別做爲第一個和第二個參數傳入 reviver 中。若是 reviver 返回 undefined,則當前屬性會從所屬對象中刪除,若是返回了其餘值,則返回的值會成爲當前屬性新的屬性值。

>當遍歷到最頂層的值(解析值)時,傳入 reviver 函數的參數會是空字符串 ""(由於此時已經沒有真正的屬性)和當前的解析值(有可能已經被修改過了),當前的 this 值會是 {"": 修改過的解析值},在編寫 reviver 函數時,要注意到這個特例。(這個函數的遍歷順序依照:從最內層開始,按照層級順序,依次向外遍歷)

stringify

JSON.stringify() 方法是將一個JavaScript值(對象或者數組)轉換爲一個 JSON字符串,若是指定了replacer是一個函數,則能夠替換值,或者若是指定了replacer是一個數組,可選的僅包括指定的屬性。mdn文檔

JSON.stringify(value[, replacer [, space]])

須要注意後面連個參數,replacer能夠是函數或者數組;

  • 數組的值表明將被序列化成JSON字符串的屬性名。
  • 做爲函數,它有兩個參數,鍵(key)值(value)都會被序列化。

    若是返回一個 Number, 轉換成相應的字符串被添加入JSON字符串。
    若是返回一個 String, 該字符串做爲屬性值被添加入JSON。
    若是返回一個 Boolean, "true" 或者 "false"被做爲屬性值被添加入JSON字符串。
    若是返回任何其餘對象,該對象遞歸地序列化成JSON字符串,對每一個屬性調用replacer方法。除非該對象是一個函數,這種狀況將不會被序列化成JSON字符串。
    若是返回undefined,該屬性值不會在JSON字符串中輸出。

注意: 不能用replacer方法,從數組中移除值(values),如若返回undefined或者一個函數,將會被null取代。

space參數用來控制結果字符串裏面的間距。若是是一個數字, 則在字符串化時每一級別會比上一級別縮進多這個數字值的空格(最多10個空格);若是是一個字符串,則每一級別會比上一級別多縮進用該字符串(或該字符串的前十個字符)。

fast-json-stringify

最近發現一個庫fast-json-stringify,由於他的介紹很簡潔:2x faster than JSON.stringify();須要一探究竟。

相關文章
相關標籤/搜索