javascript中json基础知识详解


Posted in Javascript onJanuary 19, 2017

大致介绍

JSON(JavaScript Object Notation  JavaScript对象表示法),JSON是一种数据格式,不是一种编程语言。虽然它的名字中有JavaScript但是它却不属于JavaScript,就像Java和JavaScript的关系一样。而且,并不是只有JavaScript才使用它,毕竟 JSON 只是一种数据格式。很多编程语言都有针对 JSON 的解析器和序列化器。

JSON是由Douglas Crockford在2001年提出,为了取代XML

语法

JSON的语法可以包含三种类型的值:

 ◆ 简单值

 ◆ 对象

 ◆ 数组

简单值

简单值:使用与 JavaScript 相同的语法,可以在 JSON 中表示字符串、数值、布尔值和 null

注意:【1】JSON 不支持 JavaScript 中的特殊值 undefined

           【2】JSON 字符串必须使用双引号(单引号会导致语 法错误)

// 有效的JSON数据
 "Hellow World!"
 5
 true
 null

对象

对象作为一种复杂的数据类型,表示的是一组有序的键值对,每个键值对中的值既可以是简单值也可以是复杂数据类型的值

JSON中的对象和JavaScript中的字面量稍微有一些不同:

  1、没有声明变量

  2、在末尾不需要加分号

  3、JSON 中对象的属性名任何时候都必须加双引号

注意:同一个对象中绝对不应该出现两个同名属性

// JavaScript中的字面量
 var person = {
 name : "Lao Wang",
 age : 21
 };
 // JSON
 {
 "name" : "Lao Wang",
 "age" : 21
 }
 // 可以在对象中嵌入对象
 {
 "name" : "Lao Wang",
 "age" : 21,
 "school" : {
 "name" : "TJLG",
 "location" : "西青"
 }
 }

数组

JSON 数组采用的就是 JavaScript 中的数组字面量形式

// JavaScript
 var values = [21,"西青",true];
 // JSON
 values = [21,"西青",true]

JSON对象

早期的 JSON 解析器基本上就是使用 JavaScript 的 eval()函数。由于 JSON 是 JavaScript 语法的子 集,因此 eval()函数可以解析、解释并返回 JavaScript 对象和数组,但是使用eval()函数对JSON数据结构求值存在风险,应为可能会执行一些恶意代码,所以要尽量少的使用eval()函数

ECMAScript 5 对解析 JSON 的行 为进行规范,定义了全局对象 JSON。支持这个对象的浏览器有 IE 8+、Firefox 3.5+、Safari 4+、Chrome 和 Opera 10.5+。对于较早版本的浏览器,可以使用一个 shim:https://github.com/douglascrockford/JSON-js。

JSON对象有两个方法:

1、stringify()

2、parse()

stringify()

stringify()方法将JavaScript对象序列化为JSON字符串

注意:

【1】默认情况下,JSON.stringify()输出的 JSON 字符串不包含任何空格字符或缩进

var person = {
 name : "Lao Wang",
 grade : {
 "English" : "88",
 "Math" : "98"
 }
 };
 var jsonPerson = JSON.stringify(person);
 console.log(jsonPerson);
 // {"name":"Lao Wang","grade":{"English":"88","Math":"98"}}

【2】 如果对象的成员是undefined或者函数,该成员会被忽略

如果数组的成员是undefined或者函数,则这些值会被转成null

var person = {
 name : function(){},
 sex : undefined,
 age : 21,
 grade : [undefined,function(){},"English"],
 }
 var jsonPerson = JSON.stringify(person);
 console.log(jsonPerson);
 // {"age":21,"grade":[null,null,"English"]}

【3】JSON.stringify()会忽略对象的不可遍历属性

var person = {};
 Object.defineProperties(person,{
 'name' : {
 value : "Lao Wang",
 enumerable : true
 },
 'age' : {
 value : 21,
 enumerable : false
 }
 });
 var jsonPerson = JSON.stringify(person);
 console.log(jsonPerson);
 // {"name":"Lao Wang"}

实际上,JSON.stringify()除了要序列化的 JavaScript 对象外,还可以接收另外两个参数,这两 个参数用于指定以不同的方式序列化 JavaScript 对象

第一个参数是个过滤器,可以是一个数组,也可 以是一个函数

第二个参数是一个选项,表示是否在 JSON 字符串中保留缩进

1、当第一个参数是数组时

如果过滤器参数是数组,那么 JSON.stringify()的结果中将只包含数组中列出的属性

注意:

【1】、过滤器只对对象的第一层属性有效

var person = {
 name : "Lao Wang",
 grade : {
 "English" : "88",
 "Math" : "98"
 }
 };
 var jsonPerson = JSON.stringify(person,["name","Math"]);
 console.log(jsonPerson);
 // {"name":"Lao Wang"}

【2】过滤器对数组无效

var values = [21,"he",true,"we"];
 var jsonValues = JSON.stringify(values,["he"]);
 console.log(jsonValues);
 // [21,"he",true,"we"]

2、当第一个参数是函数时

传入的函数接收两个参数,属性(键)名和属性值。根据属性(键)名可以知道应该如何处理要序列化的对象中的属性。属性名只能是字符串,而在值并非键值对儿结构的值时,键名可以是空字符串。 为了改变序列化对象的结果,函数返回的值就是相应键的值。

注意:如果函数返回了undefined或没有返回值,那么相应的属性会被忽略

var values = {
 name : "Lao Wang",
 age : 21,
 sex : "男"
 }
 var jsonValues = JSON.stringify(values,function(key,value){
 if(key == "sex"){
 return undefined;
 }else{
 return value;
 }
 });
 console.log(jsonValues);
 // {"name":"Lao Wang","age":21}

3、当给定第三个参数时

JSON.stringify()方法的第三个参数用于控制结果中的缩进和空白符。如果这个参数是一个数值,那它表示的是每个级别缩进的空格数

注意:

【1】只要传入有效的控制缩进的参数值,结果字符串就会包含换行符

【2】最大缩进空格数为10,所有大于10的值都会自动转换为10

【3】如果缩进参数是一个字符串而非数值,则这个字符串将在 JSON 字符串中被用作缩进字符(不再使用空格)

// 参数是数值
 var person = {
 name : "Lao Wang",
 grade : {
 "English" : "88",
 "Math" : "98"
 }
 };
 var jsonPerson = JSON.stringify(person,null,4);
 console.log(jsonPerson);
 /*
 {
 "name": "Lao Wang",
 "grade": {
 "English": "88",
 "Math": "98"
 }
 }
 */
 // 参数是字符串
 var person = {
 name : "Lao Wang",
 grade : {
 "English" : "88",
 "Math" : "98"
 }
 };
 var jsonPerson = JSON.stringify(person,null,"-_-||");
 console.log(jsonPerson);
 /* 
 {
 -_-||"name": "Lao Wang",
 -_-||"grade": {
 -_-||-_-||"English": "88",
 -_-||-_-||"Math": "98"
 -_-||}
 }
 */

toJSON()

有时候,JSON.stringify()还是不能满足对某些对象进行自定义序列化的需求。在这些情况下, 可以通过对象上调用toJSON()方法,返回其自身的JSON数据格式

var person = {
 name : "Lao Wang",
 grade : {
 "English" : "88",
 "Math" : "98"
 },
 toJSON : function(){
 return "toJSON方法";
 }
 };
 var jsonPerson = JSON.stringify(person);
 console.log(jsonPerson);
 // "toJSON方法"

注意:如果toJSON()方法返回undefined,此时如果包含它的对象嵌入在另一个对象中,会导致该对象的值变成null。而如果包含它的对象是顶级对象,结果就是undefined

// 嵌入在另一个对象中
 var person = {
 name : "Lao Wang",
 grade : {
 "English" : "88",
 "Math" : "98"
 },
 sex : {
 value : "男",
 toJSON : function(){
 return undefined;
 }
 }
 };
 var jsonPerson = JSON.stringify(person,null,4);
 console.log(jsonPerson);
 /*
 {
 "name": "Lao Wang",
 "grade": {
 "English": "88",
 "Math": "98"
 }
 }
 */
 // 嵌入顶级对象
 var person = {
 name : "Lao Wang",
 grade : {
 "English" : "88",
 "Math" : "98"
 },
 toJSON : function(){
 return undefined;
 }
 };
 var jsonPerson = JSON.stringify(person,null,4);
 console.log(jsonPerson);
 // undefined

原生Date对象有一个toJSON()方法,能够将JavaScript的Date 对象自动转换成ISO 8601日期字符串(与在Date对象上调用toISOString() 的结果完全一样)

var date = JSON.stringify(new Date("2017-1-18"));
 console.log(date);
 // "2017-01-17T16:00:00.000Z"

toJSON()可以作为函数过滤器的补充,因此理解序列化的内部顺序十分重要。假设把一个对象传入JSON.stringify(),序列化该对象的顺序如下

1、如果存在toJSON()方法而且能通过它取得有效的值,则调用该方法。否则,按默认顺序执行序列化

2、如果提供了第二个参数,应用这个函数过滤器。传入函数过滤器的值是第一步返回的值

3、对第二步返回的每个值进行相应的序列化

4、如果提供了第三个参数,执行相应的格式化

JSON.parse()  

 

JSON.parse()将JSON字符串解析为JavaScript值

var person = JSON.parse('{"name":"Lao Wang"}');
console.log(person.name);
// Lao Wang

注意:如果传入的字符串不是有效的JSON格式,JSON.parse方法将报错

JSON.parse()方法也可以接收另一个参数,该参数是一个函数,将在每个键值对儿上调用。为了区别 JSON.stringify()接收的替换(过滤)函数(replacer),这个函数被称为还原函数(reviver),还原函数接收两个参数,一个键和一个值,而且需要返回一个值

注意:如果还原函数返回 undefined,则表示要从结果中删除相应的键;如果返回其他值,则将该值插入到结果中

var person = JSON.parse('{"name":"Lao Wang","age":21}',function(key,value){
 if(key == "age"){
 return undefined;
 }else{
 return value;
 }
 });
 console.log(person.name);
 // Lao Wang

在将日期字符串转换为 Date 对象时,经常要用到还原函数

var book = {
 "title": "Professional JavaScript",
 "authors": ["Nicholas C. Zakas"],
 edition: 3,
 year: 2011,
 releaseDate: new Date(2017, 1, 18)
 };
 var jsonText = JSON.stringify(book,null,4);
 console.log(jsonText);
 /*
 {
 "title": "Professional JavaScript",
 "authors": [
 "Nicholas C. Zakas"
 ],
 "edition": 3,
 "year": 2011,
 "releaseDate": "2017-02-17T16:00:00.000Z"
 }
 */
 var bookCopy = JSON.parse(jsonText, function(key, value){
 if (key == "releaseDate"){
 return new Date(value);
 }else{
 return value;
 }
 });
 console.log(bookCopy.releaseDate.getFullYear()); 
 // 2017

参考资料:

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
javascript中的prototype属性使用说明(函数功能扩展)
Aug 16 Javascript
SeaJS入门教程系列之完整示例(三)
Mar 03 Javascript
jquery使用正则表达式验证email地址的方法
Jan 22 Javascript
纯js代码实现简单计算器
Dec 02 Javascript
基于JavaScript获取鼠标位置的各种方法
Dec 16 Javascript
Bootstrap datepicker日期选择器插件使用详解
Jul 26 Javascript
vue 过滤器filter实例详解
Mar 14 Javascript
vue-cli配置环境变量的方法
Jul 09 Javascript
Vue项目报错:Uncaught SyntaxError: Unexpected token
Nov 10 Javascript
jQuery利用cookie 实现本地收藏功能(不重复无需多次命名)
Nov 07 jQuery
javascript+Canvas实现画板功能
Jun 23 Javascript
Vue 事件的$event参数=事件的值案例
Jan 29 Vue.js
JavaScript实现垂直滚动条效果
Jan 18 #Javascript
JavaScript实现水平进度条拖拽效果
Jan 18 #Javascript
原生js获取浏览器窗口及元素宽高常用方法集合
Jan 18 #Javascript
基于JavaScript实现窗口拖动效果
Jan 18 #Javascript
原生js实现节日时间倒计时功能
Jan 18 #Javascript
原生js实现返回顶部缓冲效果
Jan 18 #Javascript
详解jquery validate实现表单验证 (正则表达式)
Jan 18 #Javascript
You might like
正则表达式语法
2006/10/09 Javascript
php UTF8 文件的签名问题
2009/10/30 PHP
php并发加锁示例
2016/10/17 PHP
PHP工厂模式的日常使用
2019/03/20 PHP
tagName的使用,留一笔
2006/06/26 Javascript
ASP中进行HTML数据及JS数据编码函数
2009/11/11 Javascript
jquery中实现标签切换效果的代码
2011/03/01 Javascript
js获取单选框或复选框值及操作
2012/12/18 Javascript
JS实现遮罩层效果的简单实例
2013/11/12 Javascript
jQuery获取iframe的document对象的方法
2014/10/10 Javascript
js数组依据下标删除元素
2015/04/14 Javascript
js实现目录链接,内容跟着目录滚动显示的简单实例
2016/10/15 Javascript
Bootstrap基本插件学习笔记之模态对话框(16)
2016/12/08 Javascript
Node.js 8 中的重要新特性
2017/06/28 Javascript
javascript 跨域问题以及解决办法
2017/07/17 Javascript
babel的使用及安装配置教程
2018/02/22 Javascript
微信小程序自定义对话框弹出和隐藏动画
2018/07/19 Javascript
Vue实现固定定位图标滑动隐藏效果
2019/05/30 Javascript
详解如何提升JSON.stringify()的性能
2019/06/12 Javascript
15分钟学会vue项目改造成SSR(小白教程)
2019/12/17 Javascript
JS实现吸顶特效
2020/01/08 Javascript
用Javascript实现发送短信验证码间隔功能
2021/02/08 Javascript
python动态加载变量示例分享
2014/02/17 Python
python中文编码问题小结
2014/09/28 Python
Python实现简单拆分PDF文件的方法
2015/07/30 Python
使用python和Django完成博客数据库的迁移方法
2018/01/05 Python
Python解析json时提示“string indices must be integers”问题解决方法
2019/07/31 Python
CSS3伪类选择器:nth-child()
2009/04/02 HTML / CSS
YSL圣罗兰美妆美国官网:Yves Saint Lauret US
2016/11/21 全球购物
用你熟悉的语言写一个连接ORACLE数据库的程序,能够完成修改和查询工作
2012/06/11 面试题
编写一个 C 函数,该函数在一个字符串中找到可能的最长的子字符串,且该字符串是由同一字符组成的
2015/07/23 面试题
函授大专自我鉴定
2013/11/01 职场文书
新入职员工的自我介绍演讲稿
2014/01/02 职场文书
优秀家长事迹材料(2016推荐版)
2016/02/29 职场文书
maven依赖的version声明控制方式
2022/01/18 Java/Android
Spring JPA 增加字段执行异常问题及解决
2022/06/10 Java/Android