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实验室」的微信公众号二维码,欢迎长按、扫描关注: