1.概念
全称JavaScript Object Notiation,JavaScript对象表示法,注意,它不是一种编程语言也不是什么其它,只是一种数据格式!
它是JavaScript地严格子集,利用了JS的一些模式来表示结构化的数据,但不止有JavaScript使用JSON,很多编程语言都有针对JSON的解析器和序列化器。
JSON仅仅是一种在数据传输时表示数据内容的一种方法,后面的全文都讲围绕如何使用这种方法表示数据。
JSON叫全了是JSON字符串,它是以字符串的形式存在的。
2.基础语法
JSON支持下面三种类型的值:
上面提到的这三种值均是以不具名的字面量之间呈现的,即JSON不支持变量;除此之外JSON也不支持函数、对象实例、正则表达式对象、日期对象。
3.使用
本文只介绍JavaScript中如何处理JSON格式数据。
ECMAScript5中定义了原生对象JSON,专门用于处理改格式数据(IE 8+、Firefox 3.5+、Safari 4+、Chrome和Opera 10.5+)。
但早期并没有这一原生类型,基本上在使用JS的 eval() 函数,由于JSON是JS的语法子集,所以 eval() 函数可以解析、解释并返回JavaScript对象和数组,但使用该函数对JSON数据结构求值存在风险可能会执行一些恶意代码,所以对于旧版本不支持原生JSON对象的浏览器,推荐使用一个shim:https://github.com/douglascrockford/JSON-js。
JSON对象提供两个静态方法:JSON.stringfy() 和 JSON.parse() 。前者用于将符合JSON语法的JS对象序列化为JSON格式的字符串,后者用于这一过程的逆向。
3.1 JSON.stringify()
3.1.1基础用法
用于将一个符合JSON格式的值转为JSON字符串(JSON格式的数据),并且可以被 JSON.parse() 方法还原。这一过程称为序列化。
ps:注意对于原始类型的字符串,转换结果会带双引号:
JSON.stringify(false) // "false"JSON.stringify('false') // "\"false\""
打印出结果应该为""false"",因为将来还原的时候,内层双引号可以让 JavaScript 引擎知道,这是一个字符串,而不是其他类型的值(本例中若不这样做,false就会被当作布尔类型)。
如果对象中的属性是undefined、函数、XML对象等不合法的数据类型,属性会被JSON.stringify()方法自动忽略过滤掉;若是数组成员中有这样的值,会被转换为null;该方法还会忽略掉不可遍历的属性。
var obj = {};Object.defineProperties(obj, {'foo': {value: 1,enumerable: true},'bar': {value: 2,enumerable: false}});JSON.stringify(obj); // "{"foo":1}" 其中bar就是不可遍历,所以被忽略了。
3.1.2 第二个参数
用法一:JSON.stringify() 方法还可以接受一个数组作为第二个参数,指定需要转化为字符串的属性,生成的JSON字符串将只包含数组中列出的属性,实现过滤。只对对象的属性有效。
var obj = {'prop1': 'value1','prop2': 'value2','prop3': 'value3'};var selectedProperties = ['prop1', 'prop2'];JSON.stringify(obj, selectedProperties)// "{"prop1":"value1","prop2":"value2"}"
看这三个示例时需要注意四点:
函数中return的内容;
函数第一次执行的并不是键值对,而是对象本身,无键名;
递归处理中,每一次被执行函数体内容的,都是前一次返回的值;
如果处理函数返回undefined或无返回值,该属性(键值对)会被忽略。
var o = {a: {b: 1}};function f(key, value) {console.log("["+ key +"]:" + value);return value;}JSON.stringify(o, f)// []:[object Object]// [a]:[object Object]// [b]:1// '{"a":{"b":1}}'
var o = {a: 1};function f(key, value) {if (typeof value === 'object') {return {b: 2};}return value * 2;}JSON.stringify(o, f)// "{"b": 4}"
function f(key, value) {if (typeof(value) === "string") {return undefined;}return value;}JSON.stringify({ a: "abc", b: 123 }, f)// '{"b": 123}'
还可以接受第三个参数用于增加返回的JSON字符串的可读性。
该参数为数字或字符串,如果是数字则表示每个属性前面添加的空格数(最多不超过十个),如果是字符串则之间添加在每行键值对的前面(不超过十个)。第二个参数要用null占位(不可以是空格)。
JSON.stringify({ p1: 1, p2: 2 }, null, 2);/*"{"p1": 1,"p2": 2}"*/JSON.stringify({ p1:1, p2:2 }, null, '|-');/*"{|-"p1": 1,|-"p2": 2}"*/
作为JSON.stringify()第一个参数的对象,内部如果有toJSON方法,JSON.stringify()会将toJSON方法的返回值作为第一个参数,而不是对象本身,会忽略原对象的其它属性。
toJSON方法可以自定义的,也可以是通过原生类型继承的,例如Date对象就有自己的toJSON方法:
var date = new Date('2015-01-01');date.toJSON() // "2015-01-01T00:00:00.000Z"JSON.stringify(date) // ""2015-01-01T00:00:00.000Z""
var obj = {reg: /foo/};// 不设置 toJSON 方法时JSON.stringify(obj) // "{"reg":{}}"// 设置 toJSON 方法时RegExp.prototype.toJSON = RegExp.prototype.toString;JSON.stringify(/foo/) // ""/foo/""
该方法用于将JSON字符串转成对应的值(JavaScript对象)。这一过程也称为解析。
注意JSON格式的数据是字符串,所以给该方法传参字面量最外层要带上引号,如果传的是变量则变量应为字符串类型。
如果传入的字符串不是有效的 JSON 格式,JSON.parse()方法将报错。
JSON.parse()可以接受一个处理函数作为第二个参数,用法于上文类似。
参考:
Nicholas C.Zakas,JavaScript高级程序设计-JSON
阮一峰,JavaScript教程-JSON

本教程采用知识共享 署名-相同方式共享 3.0协议。
http://creativecommons.org/licenses/by-sa/3.0/




