JSON
2016-04-04 11:22
661 查看
下述内容主要讲述了《JavaScript高级程序设计(第3版)》第20章关于“JSON”。
JSON(JavaScript Object Notation, JS对象标记)是一种数据格式,不是一种编程语言。JSON和JavaScript对象区别,就像“斑马线”和“斑马”,“斑马线”基于“斑马”身上的条纹来呈现和命名,但是“斑马”和“斑马线”是两种东西。不要混淆!
(1)简单值:可以在JSON中表示字符串(必须使用双引号)、数值、布尔值和null;但不支持JavaScript中的特殊值undefined。
(2)对象:对象的属性必须加双引号。
(3)数组:
对于不能原生支持JSON解析的浏览器,github上提供了比较优秀的shim方法:JSON-js
JSON.stringfy(“JavaScript对象”, “过滤器”, “是否缩进”):把一个JavaScript对象序列化为一个JSON字符串;值为undefined的属性会被跳过。
示例:undefined会被忽略
示例:过滤结果
(1)第二个参数是一个数组,返回只包含name和age
(2)第二个参数是一个函数
注意:如果函数返回了undefined,那么相应的属性会被忽略
(3)第三个参数控制结果中的缩进和空白符。
如果是一个数值,那他表示的是每个级别缩进的空格数;最大缩进空格数为10,大于10的自动转化为10。
如果是非数值,则这个字符将在JSON字符串中被用作缩进符(不再使用空格)。
(4)toJSON()方法,自定义序列化需求
把一个对象传入JSON.stringify(),序列化该对象的顺序如下:
如果存在toJSON()方法而且能通过它取得有效的值,则调用该方法。否则,返回对象本身。
如果提供了第二个参数,应用这个函数过滤器。传入函数过滤器的值是第(1)步返回的值。
对第(2)步返回的每个值进行相应的序列化。
如果提供了第三个参数,执行相应的格式化。
(5)序列化数值,精度丢失
根据国际标准IEEE 754,64位浮点数格式的64个二进制位中,第0位到第51位储存有效数字部分,第52到第62位储存指数部分,第63位是符号位,0表示正数,1表示负数。因此,JavaScript提供的有效数字的精度为53个二进制位(IEEE 754规定有效数字第一位默认为1,再加上后面的52位),也就是说,绝对值小于2的53次方的整数,即
转成字符串可以解决这个问题!!!
JSON(JavaScript Object Notation, JS对象标记)是一种数据格式,不是一种编程语言。JSON和JavaScript对象区别,就像“斑马线”和“斑马”,“斑马线”基于“斑马”身上的条纹来呈现和命名,但是“斑马”和“斑马线”是两种东西。不要混淆!
对比内容 | JSON | JS对象 |
---|---|---|
键名 | 必须加双引号 | 可以允许不加、加单引号、加双引号 |
属性值 | 只能是数值(10进制)、字符串(双引号)、布尔值、null、对象 | 随意(函数、NaN、Infinity、undefined) |
逗号问题 | 最后一个属性后面不能有逗号 | 可以 |
传输 | 可以跨平台数据传输,速度快 | 不可以 |
一、语法
JSON的语法可以表示三种类型的值:(1)简单值:可以在JSON中表示字符串(必须使用双引号)、数值、布尔值和null;但不支持JavaScript中的特殊值undefined。
(2)对象:对象的属性必须加双引号。
{ "name": "liang", "age": 26, "married": false, "address": null }
(3)数组:
["ligang", 25, false, null]
二、解析和序列化
早期JSON解析器基本上就是使用JavaScript的eval()函数;其存在一定的风险,可能执行一些恶意代码。对于不能原生支持JSON解析的浏览器,github上提供了比较优秀的shim方法:JSON-js
JSON.stringfy(“JavaScript对象”, “过滤器”, “是否缩进”):把一个JavaScript对象序列化为一个JSON字符串;值为undefined的属性会被跳过。
示例:undefined会被忽略
var person = { name: "liang", age: 26, address: undefined } JSON.stringify(person); // "{"name":"liang","age":26}"
示例:过滤结果
var ary = [ {name: "ligang", age: 26, sex: "male"}, {name: "camile", age: 26, sex: "female"} ];
(1)第二个参数是一个数组,返回只包含name和age
JSON.stringify(ary, ["name", "age"]); // 结果:"[{"name":"ligang","age":26},{"name":"camile","age":26}]"
(2)第二个参数是一个函数
JSON.stringify(ary, function(key, value) { switch(key) { case "name": return value; case "age": return undefined; case "sex": return value === "male" ? "男" : "女"; default: return value; } }); // 结果:"[{"name":"ligang","sex":"男"},{"name":"camile","sex":"女"}]"
注意:如果函数返回了undefined,那么相应的属性会被忽略
(3)第三个参数控制结果中的缩进和空白符。
如果是一个数值,那他表示的是每个级别缩进的空格数;最大缩进空格数为10,大于10的自动转化为10。
如果是非数值,则这个字符将在JSON字符串中被用作缩进符(不再使用空格)。
var person = { name: "ligang", address: { province: "shandong", city: "yantai" } }; JSON.stringify(person, null, 4); // 结果: { "name": "ligang", "address": { "province": "shandong", "city": "yantai" } }" JSON.stringify(person, null, "--"); // 结果: "{ --"name": "ligang", --"address": { ----"province": "shandong", ----"city": "yantai" --} }"
(4)toJSON()方法,自定义序列化需求
var person = { name: "ligang", age: 26, toJSON: function() { return this.name + "|" + this.age; } }; JSON.stringify(person); // 结果:""ligang|26""
把一个对象传入JSON.stringify(),序列化该对象的顺序如下:
如果存在toJSON()方法而且能通过它取得有效的值,则调用该方法。否则,返回对象本身。
如果提供了第二个参数,应用这个函数过滤器。传入函数过滤器的值是第(1)步返回的值。
对第(2)步返回的每个值进行相应的序列化。
如果提供了第三个参数,执行相应的格式化。
var person = { firstName: "li", lastName: "gang", age: 26, toJSON: function() { return {name: this.firstName + this.lastName, age: this.age}; } }; JSON.stringify(person, function(key, value){ switch(key){ case "age": return undefined; default: return value; } }, "--"); // 结果: "{ --"name": "ligang" }"
(5)序列化数值,精度丢失
JSON.stringify({id:14812712740571735}); // "{"id":14812712740571736}"
根据国际标准IEEE 754,64位浮点数格式的64个二进制位中,第0位到第51位储存有效数字部分,第52到第62位储存指数部分,第63位是符号位,0表示正数,1表示负数。因此,JavaScript提供的有效数字的精度为53个二进制位(IEEE 754规定有效数字第一位默认为1,再加上后面的52位),也就是说,绝对值小于2的53次方的整数,即
-(Math.pow(2, 53)-1)到
Math.pow(2, 53)-1,都可以精确表示。即16位数!
转成字符串可以解决这个问题!!!
JSON.stringify({id:"14812712740571735"}); // "{"id":"14812712740571735"}"
三、解析选项
JSON.parse(jsonText, fn),将JSON字符串解析为JavaScript值。fn将在每个键值对上调用。如果函数返回undefined,则要从结果中删除相应的键。var person = { name: "ligang", age: 26, birthday: new Date(1990, 02, 28) }; var jsonText = JSON.stringify(person); // "{"name":"ligang","age":26,"birthday":"1990-03-27T16:00:00.000Z"}" var jsonObj = JSON.parse(jsonText, function(key, value) { if(key === "birthday") { return new Date(value); }else { return value; } }); console.log(jsonObj.birthday.getFullYear()); // 1990
相关文章推荐
- JQuery1——基础($对象,选择器,对象转换)
- Android学习笔记(二九):嵌入浏览器
- Android java 与 javascript互访(相互调用)的方法例子
- Python动态类型的学习---引用的理解
- JavaScript演示排序算法
- javascript实现10进制转为N进制数
- 最后一次说说闭包
- Ajax
- XML 与 JSON 优劣对比
- 2019年开发人员应该学习的8个JavaScript框架
- HTML中的script标签研究
- 对一个分号引发的错误研究
- 异步流程控制:7 行代码学会 co 模块
- ES6 走马观花(ECMAScript2015 新特性)
- JavaScript拆分字符串时产生空字符的原因
- Canvas 在高清屏下绘制图片变模糊的解决方法
- Redux系列02:一个炒鸡简单的react+redux例子