JSON(Javascript Object Notaion, javascript 對象表示法), 是一種數據交換格式,可以在服務器端交換數據, 2001年由Douglas Crockford提出,目的是取代繁瑣笨重的XML格式。javascript
JSON 數據格式的優勢:java
JSON 創建在兩種數據結構上:git
{ "key": "value" }
["value", "value", "value"]
合格的 JSON 格式:github
{ "name": "煦涵", "name": null, "male": true, "age": 23 } { "brother": ["煦涵1", "煦涵2"] } { "brother": { "煦涵1": { "age": 32 }, "煦涵2": { "age": 30 } } } [{ "name": "煦涵" "age": 30 },{ "name": "張三" "age": 27 }]
不合格的 JSON 格式:正則表達式
// key 必須用雙引號包裹,value 若是是字符串必須用雙引號包裹 { 'name': "煦涵" } [1, 2, 3, 4, oxFOF] { 'name': undefined } { 'name': function() { return "煦涵" } } { 'name': new Date() }
若是value的一個String(雙引號包圍)內包含 \"
、\\
、\/
、\b
、\f
、\n
、\r
、\t
、\u001f
須要使用反斜槓
若是value的一個Number,不能使用八進制和十六進制數值
PS: value對空格沒有限制要求編程
聊完 JSON 下面咱們來聊聊 JSON 對象,javascript 在 ES5中新增了 JSON 對象,用來處理 JSON 文本數據,實現字符串與 JSON 對象間的相互轉換,JSON.stringify ( value [ , replacer [ , space ] ] )
和 JSON.parse ( text [ , reviver ] )
, 前者是把 JSON 對象轉換爲 JSON 字符串,後者的把 JSON 字符串解析爲 JSON 對象,下面來詳細看看這個兩個方法。json
JSON.stringify({ "name": "煦涵", "age" : 28, "male" : true, "brother": [1, 2, 3], "parent": { "father" : { "name": "name" }, "mother": { "name": "name" } }, "other": null }) // result "{"name":"煦涵","age":28,"male":true,"brother":["B1","B2","B3"],"parent":{"father":{"name":"name"},"mother":{"name":"name"}},"other":null}"
當待轉換值不是 JSON 的基本類型時:數組
JSON.stringify({ "name": undefined, "age" : function() {return 28}, "male" : /male/g, "brother": [undefined, function() {return abc}, "B3", 0xFOF], "parent": { "father" : { "name": undefined }, "mother": { "name": "name" } }, "other": null }) // result: 正則被轉出了空對象,undefined, function 被忽略或者轉成 null "{"male":{},"brother":[null,null,"B3", 3855],"parent":{"father":{},"mother":{"name":"name"}},"other":null}" /* 不可遍歷屬性 */ var demo = {}; Object.defineProperties(demo, { "name": { value: "煦涵", enumerable: false }, "age": { value: 28, enumerable: true } }) JSON.stringify(demo); // enumerable: 當且僅當該屬性的 enumerable 爲 true 時,該屬性纔可以出如今對象的枚舉屬性中, // result: name 屬性會被過濾 "{"age":28}" /* 特殊字符處理-01 */ JSON.stringify({ "special01": "回車 \r,換行 \n,退格 \b,換頁 \f,Tab \t", "special02": "雙引號 \",單引號 ', 斜槓 \/, 反斜槓 \\", "special03": "unicdoe字符 \u001f" }) // result '{"special01":"回車 \r,換行 \n,退格 \b,換頁 \f,Tab \t","special02":"雙引號 \",單引號 ', 斜槓 /, 反斜槓 \\","special03":"unicdoe字符 \u001f"}' /* 特殊字符處理-02 */ var demo = {} demo.special01 = '回車 \r,換行 \n,退格 \b,換頁 \f,Tab \t'; demo.special02 = '雙引號 ",斜槓 /, 反斜槓\,end '; demo.special03 = 'unicdoe字符 \u001f'; JSON.stringify(demo); // result, 雙引號被轉義了,反斜槓被忽略了 '{"special01":"回車 \r,換行 \n,退格 \b,換頁 \f,Tab \t","special02":"雙引號 \",斜槓 /, 反斜槓,end ","special03":"unicdoe字符 \u001f"}'
/* replacer 爲數組 */ JSON.stringify({ "0": "安徽省", "1": "蚌埠市", "2": "固鎮縣" }, [0,1]) // result: '{"0":"安徽省","1":"蚌埠市"}' JSON.stringify([ "安徽省", "蚌埠市", "固鎮縣" ], [0,1]) // result '["安徽省","蚌埠市","固鎮縣"]' /* replacer 爲函數 */ JSON.stringify({ "0": "安徽省", "1": "蚌埠市", "2": "固鎮縣" }, function(key, value) { // key: '', value: {0: "安徽省", 1: "蚌埠市", 2: "固鎮縣"} console.log(key, value); return value[0] + value[1] + value[2]; }) // result ""安徽省蚌埠市固鎮縣""
JSON.stringify({"name": "煦涵", "age": 28, "male": true, "other": null}, '', 4) // result "{ "name": "煦涵", "age": 28, "male": true, "other": null }" JSON.stringify({"level1": {"level2": {"level3": {"name": "煦涵"} } } }, '', '|---') // result: 展現屬性結構很直觀 "{ |---"level1": { |---|---"level2": { |---|---|---"level3": { |---|---|---|---"name": "煦涵" |---|---|---} |---|---} |---} }"
JSON.stringify({ "name": "煦涵", "age": 28, "toJSON": function() { return this.name + '年齡是' + this.age + '歲' } }) // result: ""煦涵年齡是28歲"" /* 日期對象Date原型上包含toJSON 方法,`Date.prototype.toJSON ( key )` */ var date = new Date(); date.toJSON(); JSON.stringify(date); /* RegExp 對象 JSON.stringify 默認會把正則轉換成空對象,咱們可使用toJSON, 把正則表達式轉換成字符串 */ RegExp.prototype.toJSON = RegExp.prototype.toString; JSON.stringify(/abc/g) // result ""/abc/g""
JSON.parse爲 JSON.stringify的逆運算,轉換時 text 必須符合JSON的語法格式, 否則會報錯,reviver 參數 和 JSON.stringify 的參數 replacer相似, 可是遍歷順序和replacer相反。服務器
JSON.parse('{"name":"煦涵","age":28,"male":true,"brother":["B1","B2","B3"],"parent":{"father":{"name":"name"},"mother":{"name":"name"}},"other":null}' ) /* result: { "name": "煦涵", "age" : 28, "male" : true, "brother": ["B1", "B2", "B3"], "parent": { "father" : { "name": "name" }, "mother": { "name": "name" } }, "other": null } */ JSON.parse('{"level1": {"level2": {"name": "煦涵"} } }', function(key, value) { // level2 Object {name: "煦涵"} // level1 Object {level2: Object} // Object {level1: Object} console.log(key, value); return value; }) // result {"level1":{"level2":{"name":"煦涵"}}}
http://www.ecma-international.org/ecma-262/5.1/#sec-15.12
https://github.com/douglascrockford/JSON-js/blob/master/json2.js
http://www.json.org/微信
感謝您的閱讀
--eof--
做者[煦涵]
2017年04月30日
下面是「FED實驗室」的微信公衆號二維碼,歡迎長按、掃描關注: