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 相关文章推荐
实现点击列表弹出列表索引的两种方式
Mar 08 Javascript
jqgrid 表格数据导出实例
Nov 21 Javascript
js二维数组排序的简单示例代码
Jan 24 Javascript
浅析jquery的js图表组件highcharts
Mar 06 Javascript
JavaScript通过事件代理高亮显示表格行的方法
May 27 Javascript
javascript实现网页端解压并查看zip文件
Dec 15 Javascript
详解有关easyUI的拖动操作中droppable,draggable用法例子
Jun 03 Javascript
浅谈JavaScript的innerWidth与innerHeight
Oct 12 Javascript
Angular中点击li标签实现更改颜色的核心代码
Dec 08 Javascript
高性能的javascript之加载顺序与执行原理篇
Jan 14 Javascript
解决vuecli3.0热更新失效的问题
Sep 19 Javascript
Vue实现简单的拖拽效果
Aug 25 Javascript
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
PHP 编程的 5个良好习惯
2009/02/20 PHP
php中使用array_filter()函数过滤空数组的实现代码
2014/08/19 PHP
如果文字过长,则将过长的部分变成省略号显示
2006/06/26 Javascript
JavaScript中出现乱码的处理心得
2009/12/24 Javascript
js实现在字符串中提取数字
2013/11/05 Javascript
javascript对话框使用方法(警告框 javascript确认框 提示框)
2014/01/07 Javascript
分享28款免费实用的 JQuery 图片和内容滑块插件
2014/12/15 Javascript
通过XMLHttpRequest和jQuery实现ajax的几种方式
2015/08/28 Javascript
JS实现的3D拖拽翻页效果代码
2015/10/31 Javascript
jQuery ajax方法传递中文时出现中文乱码的解决方法
2016/07/25 Javascript
JS模拟实现ECMAScript5新增的数组方法
2017/03/20 Javascript
webpack2.0搭建前端项目的教程详解
2017/04/05 Javascript
Vue.js 实现微信公众号菜单编辑器功能(一)
2018/05/08 Javascript
浅谈React的最大亮点之虚拟DOM
2018/05/29 Javascript
Javascript 关于基本类型和引用类型的个人理解
2019/11/01 Javascript
vue  elementUI 表单嵌套验证的实例代码
2019/11/06 Javascript
实用的 vue tags 创建缓存导航的过程实现
2020/12/03 Vue.js
用Python给文本创立向量空间模型的教程
2015/04/23 Python
黑科技 Python脚本帮你找出微信上删除你好友的人
2016/01/07 Python
Python基于回溯法子集树模板解决0-1背包问题实例
2017/09/02 Python
浅谈python实现Google翻译PDF,解决换行的问题
2018/11/28 Python
python2和python3实现在图片上加汉字的方法
2019/08/22 Python
python Kmeans算法原理深入解析
2019/08/23 Python
python base64库给用户名或密码加密的流程
2020/01/02 Python
Python3实现飞机大战游戏
2020/04/24 Python
python爬取代理ip的示例
2020/12/18 Python
Nuts.com:优质散装,批发坚果、干果和巧克力等
2017/03/21 全球购物
英国街头品牌:Bee Inspired Clothing
2018/02/12 全球购物
斯洛伐克香水和化妆品购物网站:Parfemy-Elnino.sk
2020/01/28 全球购物
PHP如何去执行一个SQL语句
2016/03/05 面试题
什么是重载?CTS、CLS和CLR分别做何解释
2012/05/06 面试题
心理健康心得体会
2014/01/02 职场文书
毕业生自荐书
2014/02/02 职场文书
水浒传读书笔记
2015/06/25 职场文书
聘任通知书
2015/09/21 职场文书
公安干警正风肃纪心得体会
2016/01/15 职场文书