JavaScript解析及序列化JSON的方法实例分析


Posted in Javascript onJanuary 04, 2019

本文实例讲述了JavaScript解析及序列化JSON的方法。分享给大家供大家参考,具体如下:

JSON 之所以这么流行,是因为 JSON 数据结构可以被解析为 JavaScript 对象。JSON 之前的 XML 数据结构要被解析,需要先解析成 DOM 文档,然后再从中提取出数据。相比之下,JSON 数据结构方便多咯O(∩_∩)O~

所以 JSON 就成为 web 开发中,用于数据交换的事实标准。

1 JSON 对象

早期的 JSON 解析器是使用 JavaScript 的 eval() 函数。因为 JSON 是 JavaScript 语法的子集,所以 eval() 函数可以解析并返回 JavaScript 对象。但使用这个函数存在风险,因为有可能会被执行一些恶意的代码!ECMAScript 5 定义了全局对象 JSON。支持这个对象的浏览器有 IE8+、Firefox 3.5+、Safari 4+、Chrome 和 Opera 10.5+。而旧版的浏览器建议使用 JSON-js 库。

JSON 对象有两个方法:

1. stringify(),会把 JavaScript 对象序列化为 JSON 字符串。
2. parse(),会把 JSON 字符串解析为原生的 JavaScript 对象。

<script type="text/javascript">
var book = {
  title: "music",
  authors: ["deniro"],
  edition: 1,
  year: 2017
};
var jsonText = JSON.stringify(book);
console.log(jsonText);
var bookCopy = JSON.parse(jsonText);
console.log(bookCopy);
</script>

默认情况下,JSON.stringify() 输出的字符串不包含任何空格字符以及缩进。而且所有的函数以及原型成员都会被有意忽略。此外,值为 undefined 的属性也会被跳过。所以结果中都是值为有效的属性。

注意:上面代码中的 book 与 bookCopy 虽然具有相同的属性,但它们是两个独立的、没有任何关系的对象。

如果传给 JSON.parse() 的字符串不是有效的 JSON 字符串,就会抛出错误。

2 序列化选项

JSON.stringify() 还可以接收另外两个参数。第二个参数是过滤器,可以是数组,也可以是函数;第三个参数表示是否在 JSON 字符串中保留缩进。

2.1 过滤结果

如果过滤器的参数是数组,那么结果中将只会包含这个数组所列出的属性:

<script type="text/javascript">
var book = {
  title: "music",
  authors: ["deniro"],
  edition: 1,
  year: 2017
};
//过滤结果
var jsonTextAfterFilter=JSON.stringify(book,["title","edition"]);
console.log(jsonTextAfterFilter);//{"title":"music","edition":1}
</script>

如果过滤器的参数是函数,那么这个函数会接收两个参数,属性名和属性值。属性名只能是字符串,如果它所对应的属性值不是键值对结构的值时,那么属性名可以是空字符串。这个函数的返回值就是相应属性名对应的值。如果函数返回 undefined,那么相应的属性就会被忽略:

<script type="text/javascript">
  var book = {
    title: "music",
    authors: ["deniro"],
    edition: 1,
    year: 2017
  };
  var jsonText = JSON.stringify(book, function (key, value) {
    switch (key) {
      case "authors":
        return value.join(",");
      case "year":
        return 10000;
      case "edition":
        return undefined;
      default :
        return value;
    }
  });
  console.log(jsonText);//{"title":"music","authors":"deniro","year":10000}
</script>

注意:一定要提供 default 选项,这样才能保证其他的值都能正常地出现在结果中。

Firefox 3.5 和 3.6 有一个 bug,在将函数作为方法的第二个参数时,只有返回 undefined 有效,而返回其他任何值都会在结果中包含相应的属性,Firefox 4 修复了这个 bug。

2.2 字符串缩进

JSON.stringify() 的第三个参数可以控制结果中的缩进和空白符。如果这个参数是数值,那么就表示是缩进的空格数,比如这里要缩进 4 个空格:

<script type="text/javascript">
  var book = {
    title: "music",
    authors: ["deniro"],
    edition: 1,
    year: 2017
  };
  var jsonText = JSON.stringify(book, null, 4);
  console.log(jsonText);
</script>

使用在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun测试上述代码,运行结果如下:

JavaScript解析及序列化JSON的方法实例分析

除了缩进,JSON.stringify() 也在结果中添加了换行符,这提高了 JSON 字符串的可读性。最大缩进空格数为 10,超过这个值都会被自动转为 10。

如果缩进参数是一个字符串,那么它会作为 JSON 字符串的缩进字符:

<script type="text/javascript">
var book = {
  title: "music",
  authors: ["deniro"],
  edition: 1,
  year: 2017
};
var jsonTextWithIndent=JSON.stringify(book,null,"--");//传入缩进字符
console.log(jsonTextWithIndent);
</script>

使用在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun测试上述代码,运行结果如下:

JavaScript解析及序列化JSON的方法实例分析

缩进字符串最长不能超过 10,如果超过了这个值,结果中就只会出现前 10 个字符。

2.3 toJSON() 方法

有时候,JSON.stringify() 不能满足某些对象的自定义序列化的要求。这时,我们可以使用对象上的 toJSON() 方法,返回其自身的 JSON 数据格式。

可以为任何对象添加 toJSON() 方法:

<script type="text/javascript">
  var book = {
    title: "music",
    authors: ["deniro"],
    edition: 1,
    year: 2017,
    toJSON: function () {
      return this.title;
    }
  };
  var jsonText = JSON.stringify(book);
  console.log(jsonText);//"music"
</script>

可以让 toJSON() 方法返回任何序列化的值;也可以返回 undefined,这时如果包含它的对象嵌入在另一个对象中,那么这个对象的值就会变成 null,如果包含的它的对象是顶级对象,那么这个对象就是 undefined

一个对象传入 JSON.stringify() 时,序列化该对象的顺序是这样的:
①. 如果存在 toJSON() 方法而且能通过它取得有效值时,就调用该方法。
②. 如果提供了第二个参数,就应用这个函数过滤器,传入这个过滤器的值是上一步返回的值。
③. 对第二步返回的每个值进行相应的序列化。
④. 如果提供了第三个参数,就执行相应的格式化操作。

3 解析选项

JSON.parse() 也可以接收第二个参数,它是一个函数,这个函数会在每个键值对上调用,这个函数被称为还原函数,它接收一个键和一个值,需要一个返回值。

如果这个还原函数返回 undefined,就表示要从结果中删除相应的键;如果返回其他值,则会将该值插入到结果中。在将日期字符串转换为 Date 对象时,经常要用到这个函数:

<script type="text/javascript">
  var book = {
    title: "music",
    authors: ["deniro"],
    edition: 1,
    year: 2017,
    releaseDate: new Date(2017, 6, 2)
  };
  var jsonText = JSON.stringify(book);
  var bookCopy = JSON.parse(jsonText, function (key, value) {
    if (key == "releaseDate") {
      return new Date(value);
    } else {
      return value;
    }
  });
  console.log(bookCopy.releaseDate.getFullYear());
</script>

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun测试上述代码运行效果。

Javascript 相关文章推荐
jquery checkbox全选、取消全选实现代码
Mar 05 Javascript
js实现无需数据库的县级以上联动行政区域下拉控件
Aug 14 Javascript
JS中自定义定时器让它在某一时刻执行
Sep 02 Javascript
JS实现简单的图书馆享元模式实例
Jun 30 Javascript
js过滤HTML标签完整实例
Nov 26 Javascript
JavaScript中实现无缝滚动、分享到侧边栏实例代码
Apr 06 Javascript
underscore之Collections_动力节点Java学院整理
Jul 10 Javascript
原生JS实现 MUI导航栏透明渐变效果
Nov 07 Javascript
angular2系列之路由转场动画的示例代码
Nov 09 Javascript
微信小程序实现文字从右向左无限滚动
Nov 18 Javascript
vue搜索和vue模糊搜索代码实例
May 07 Javascript
简谈创建React Component的几种方式
Jun 15 Javascript
Node.js操作系统OS模块用法分析
Jan 04 #Javascript
Node.js console控制台简单用法分析
Jan 04 #Javascript
Node.js JSON模块用法实例分析
Jan 04 #Javascript
使用VUE+iView+.Net Core上传图片的方法示例
Jan 04 #Javascript
Node.js assert断言原理与用法分析
Jan 04 #Javascript
如何为vuex实现带参数的 getter和state.commit
Jan 04 #Javascript
原生javascript实现连连看游戏
Jan 03 #Javascript
You might like
双料怀旧--SHARP GF515的维护、修理和简单调试
2021/03/02 无线电
php中使用array_filter()函数过滤空数组的实现代码
2014/08/19 PHP
php微信公众号开发(2)百度BAE搭建和数据库使用
2016/12/15 PHP
JavaScript 存在陷阱 删除某一区域所有节点
2010/05/10 Javascript
javascript 终止函数执行操作
2014/02/14 Javascript
javascript页面渲染速度测试脚本分享
2014/04/15 Javascript
超精准的javascript验证身份证号的具体实现方法
2015/11/18 Javascript
学习javascript面向对象 理解javascript对象
2016/01/04 Javascript
jQuery解析json格式数据简单实例
2016/01/22 Javascript
原生js获取iframe中dom元素--父子页面相互获取对方dom元素的方法
2016/08/05 Javascript
nodejs基础知识
2017/02/03 NodeJs
React学习笔记之列表渲染示例详解
2017/08/22 Javascript
js定时器实现倒计时效果
2017/11/05 Javascript
vue组件生命周期详解
2017/11/07 Javascript
ES6 系列之 WeakMap的使用示例
2018/08/06 Javascript
浅谈Vue页面级缓存解决方案feb-alive(上)
2019/04/14 Javascript
详解vue中使用vue-quill-editor富文本小结(图片上传)
2019/04/24 Javascript
vuejs数据超出单行显示更多,点击展开剩余数据实例
2019/05/05 Javascript
微信小程序webSocket的使用方法
2020/02/20 Javascript
JS端基于download.js实现图片、视频时直接下载而不是打开预览
2020/05/09 Javascript
django框架model orM使用字典作为参数,保存数据的方法分析
2019/06/24 Python
Python中栈、队列与优先级队列的实现方法
2019/06/30 Python
python对常见数据类型的遍历解析
2019/08/27 Python
html5 canvas 简单画板实现代码
2012/01/05 HTML / CSS
联想香港官方网站及网店:Lenovo香港
2018/04/13 全球购物
机械制造专业个人的自我评价
2013/12/28 职场文书
员工年终演讲稿
2014/01/03 职场文书
汉语言文学毕业生自荐信范文
2014/03/24 职场文书
员工安全承诺书
2014/05/22 职场文书
药剂专业自荐书
2014/06/20 职场文书
党的群众路线教育实践活动对照检查材料
2014/09/22 职场文书
单身申明具结书
2015/02/26 职场文书
2015年行政人事工作总结
2015/05/21 职场文书
工作简历的自我评价
2019/05/16 职场文书
导游词之湖北梁子湖
2019/11/07 职场文书
Spring Boot 排除某个类加载注入IOC的操作
2021/08/02 Java/Android