JSON(JavaScript Object Notation)
,指JavaScript
的对象表示法,它自己是个字符串,是一种数据交换格式,并不是对象。一般所提的JSON
对象实际是JSON
字符串解析成对象的结果,或是浏览器window
对象下的JSON
对象。javascript
并且JSON
不止用于JavaScript
中,其普遍用于数据交换。html
一个JSON
文件,或一段JSON
字符串,一般是这样的:java
[{ "name": "用户权限管理", "code": "99990002", "icon": "modicon-1", "items": [{ "name": "模块权限", "code": "999900020009", "url": "", "isBlank": false, "items": [{ "name": "向导模板", "code": "9999000200090003", "url": "pages/accLayoutTest.html", "isBlank": false, "items": [] }, { "name": "模块管理咱们的", "code": "9999000200090001", "url": "pages/contentPageTest.html", "isBlank": false, "items": [] }] }] }, ... ]
而这样相似的JavaScript
对象则是这样的:git
var menuData = [{ name: "用户权限管理", code: "99990002", icon: "modicon-1", items: [{ name: "模块权限", code: "999900020009", url: "", isBlank: false, items: [{ name: "向导模板", code: "9999000200090003", url: "pages/accLayoutTest.html", isBlank: false, items: [] }, { name: "模块管理咱们的", code: "9999000200090001", url: "pages/contentPageTest.html", isBlank: false, items: [] }] }] }, ...]
二者很是的类似,所不一样的是就是JavaScript
对象中属性名,也就是对象的key
值是能够没有引号的,其值为字符串时,使用''
和""
包裹都可。 所以咱们不少人将第一段代码块里所写的JSON
称为JSON对象,实际上,它并非一个对象,只是一个单纯的字符串而已,可是它符合JSON
的语法规则,能够很方便地转化为JavaScript
对象,或者方便地用于数据交换。github
如下咱们来了解一下JSON
。ajax
JSON语法规则正则表达式
JSON 语法是 JavaScript 对象表示语法的子集,其基本原则以下:json
数据在键值对中数组
数据由逗号分隔浏览器
花括号保存对象
方括号保存数组
JSON的值
数字(整数或浮点数)
字符串(在双引号中)
逻辑值(true
或 false
)
数组(在方括号中[]
)
对象(在花括号中{}
)
null
JSON
做为一种数据交换格式,为了保证其能被正确方便的解析,其格式有严格的要求,必须遵循如下规则:
复合类型的值只能是数组或对象,不能是函数、正则表达式对象、日期对象。
简单类型的值只有四种:字符串、数值(必须以十进制表示)、布尔值和null
(不能使用NaN
, Infinity
, -Infinity
和undefined
)。
字符串必须使用双引号表示,不能使用单引号。
对象的键名必须放在双引号里面。
数组或对象最后一个成员的后面,不能有逗号。
数值前不能加0。
如下是合法的JSON
格式示例:
["one", "two", "three"] { "one": 1, "two": 2, "three": 3 } { "names": [ "张三", "李四" ] } [ { "name": "张三" }, { "name": "李四" } ]
下面这些就是不合法的:
{ name: "张三", 'age': 32 } // 属性名必须使用双引号 [32, 64, 128, 0xFFF] // 不能使用十六进制值 { "name": "张三", "age": undefined } // 不能使用undefined { "name": "张三", "birthday": new Date('Fri, 26 Aug 2011 07:13:10 GMT'), "getName": function() { return this.name; } } // 不能使用函数和日期对象 { "name": "李四", "age": 018 } // 数值前不能有0
以上代码中为了指出错误所在,使用了
JavaScript
的注释法,实际JSON
中是不能有注释的。不合法的
JSON
会在解析成JavaScript
对象时,出现错误。
JSON
做为一种数据交换格式,被写入了ECMAScript 5,在IE8及以后的浏览器都提供了一个JSON
对象,用于对JSON
进行解析和序列化。
此方法接收一个JSON
字符串,返回解析后的JavaScript对象,一般为Object
或Array
。
// JSON数据 var humansData = '[{"name":"zs","age":28},{"name":"ls","age":26}]'; // 解析为JavaScript对象 var humans = JSON.parse(humansData); // 以后就能够访问其元素或属性了 humans[1].name; // ls humans[1].age; // 26
若是传入不合法的
JSON
,则会在JSON.parse
时报错。
为何咱们在ajax请求中,即便请求的数据为JSON
,咱们不用解析就能直接使用呢?
// test.text内容 /* [{ "name":"zs", "age":28 },{ "name":"ls", "age":26 }] */ $.ajax({ url: './test/test.text', dataType: 'JSON' }).done(function(data){ console.dir(data); // Array[2] console.log(data[0].name); // zs // 这里没有转化为js对象就能访问其属性?! });
这里实际是由于指定了dataType
为JSON,从而进行了自动转化,因此能直接在成功回调中使用其属性。若是去掉dataType
的指定,就不能直接访问其属性了,由于未转化时,其自己是一个字符串。第一行输出为test.text的内容,第二行输出undefined
。
此方法可接收一个JavaScript
值将转化为JSON
字符串,此字符串可被JSON.parse
还原。
var humans = [{ "name": "zs", "age": 28, "birth": new Date() }, { "name": "ls", "age": 26, "birth": new Date() }]; // 转化为JSON字符串 JSON.stringify(humans); // "[{"name":"zs","age":28,"birth":"2016-10-25T07:24:11.701Z"},{"name":"ls","age":26,"birth":"2016-10-25T07:24:11.701Z"}]"
前面咱们讲到了JSON
中并不是支持全部的JavaScript
类型,所以此方法对一些JSON
不可接受的值有所处理:原始对象中,若是有一个成员的值是undefined、函数或XML对象,这个成员会被省略。若是数组的成员是undefined、函数或XML对象,则这些值被转成null。
咱们还发现,JSON
中是不支持Date
对象的,而上述转化为字符串的结果中正确包含了birth
的值,其为一个日期格式的字符串。这是由于在Date
对象上有一个名为toJSON
的方法,JSON.stringify
在序列化时,实际是调用了这个方法来输出结果的。
若是一个被序列化的对象拥有 toJSON 方法,那么该 toJSON 方法就会覆盖该对象默认的序列化行为:不是那个对象被序列化,而是调用 toJSON 方法后的返回值会被序列化,例如:
var obj = { foo: 'foo', toJSON: function() { return 'bar'; } }; JSON.stringify(obj); // '"bar"' JSON.stringify({x: obj}); // '{"x":"bar"}'
了解便可,详见: MDN:JSON.stringify(){.doc-link}
咱们可能常常看到的是JSON.stringify( obj , null , 4)
,这样是什么意思呢?
对于上例,替换最后一句,结果以下所示:
JSON.stringify(humans, null, 4); // "[ // { // "name": "zs", // "age": 28, // "birth": "2016-10-25T07:24:11.701Z" // }, // { // "name": "ls", // "age": 26, // "birth": "2016-10-25T07:24:11.701Z" // } // ]"
其实没什么变化,不过是加上了空格缩进,使得可读性更高了。
其他两个参数的说明以下:
第二个参数可指定序列化时的操做。
若是该参数是一个函数,则在序列化过程当中,被序列化的值的每一个属性都会通过该函数的转换和处理;
若是该参数是一个数组,则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中;
若是该参数为null或者未提供,则对象全部的属性都会被序列化;
第三个参数用于指定缩进用的空白字符串,用于美化输出(pretty-print);
若是参数是个数字,它表明有多少的空格;上限为10。该值若小于1,则意味着没有空格;
若是该参数为字符串(字符串的前十个字母),该字符串将被做为空格;
若是该参数没有提供(或者为null)将没有空格。
window.JSON
对象下虽然提供了完整的JSON
字符串和JavaScript
对象的转换方法。可是在IE8(兼容模式)以及更低版本的IE下没有提供这个对象,所以咱们须要一些替代方案。
jQuery中提供了parseJSON
这样一个方法来替代JSON.parse
,它接收一个标准格式的JSON
字符串,返回一个解析后的JavaScript
对象。
使用http://www.json.org/提供了一个json.js,这样ie8(兼容模式),ie7和ie6就能够支持JSON对象以及其stringify()
和parse()
方法; 能够在https://github.com/douglascrockford/JSON-js上获取到这个js,通常如今用json2.js。
还可使用 eval('(' + jsonstr + ')')
; 来将json字符串转换成json对象,注意须要在json字符外包裹一对小括号。但最好不要使用这种方式,由于这种方式不安全,eval
会将JSON
字符串做为JavaScript
语句来执行,JSON
中的风险代码将被执行。