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 相关文章推荐
图片按比例缩放函数
Jun 26 Javascript
javascript读取xml
Nov 04 Javascript
javascript支持firefox,ie7页面布局拖拽效果代码
Dec 20 Javascript
JQuery扩展插件Validate 5添加自定义验证方法
Sep 05 Javascript
jquery简单实现带渐显效果的选项卡菜单代码
Sep 01 Javascript
CascadeView级联组件实现思路详解(分离思想和单链表)
Apr 12 Javascript
AngularJS入门教程之AngularJS 模板
Aug 18 Javascript
vue.js选中动态绑定的radio的指定项
Jun 02 Javascript
使用axios实现上传图片进度条功能
Dec 21 Javascript
react 实现页面代码分割、按需加载的方法
Apr 03 Javascript
加快Vue项目的开发速度的方法
Dec 12 Javascript
图文讲解用vue-cli脚手架创建vue项目步骤
Feb 12 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
APACHE的AcceptPathInfo指令使用介绍
2013/01/18 PHP
事件冒泡是什么如何用jquery阻止事件冒泡
2013/03/20 Javascript
JQuery-tableDnD 拖拽的基本使用介绍
2013/07/04 Javascript
js模拟点击以提交表单为例兼容主流浏览器
2013/11/29 Javascript
node.js下when.js 的异步编程实践
2014/12/03 Javascript
jquery增加和删除元素的方法
2015/01/14 Javascript
jquery+php随机生成红包金额数量代码分享
2015/08/27 Javascript
javascript禁止超链接跳转的方法
2016/02/02 Javascript
jQuery实现根据滚动条位置加载相应内容功能
2016/07/18 Javascript
解析JavaScript数组方法reduce
2016/12/12 Javascript
详解Angularjs 如何自定义Img的ng-load 事件
2017/02/15 Javascript
vue + socket.io实现一个简易聊天室示例代码
2017/03/06 Javascript
浅析Angular19 自定义表单控件
2018/01/31 Javascript
基于ts的动态接口数据配置的详解
2019/12/18 Javascript
JavaScript仿京东秒杀倒计时
2020/03/17 Javascript
[01:58]DOTA2上海特级锦标赛现场采访:RTZ这个ID到底好不好
2016/03/25 DOTA
python正则分组的应用
2013/11/10 Python
举例讲解Python设计模式编程的代理模式与抽象工厂模式
2016/01/16 Python
理解生产者消费者模型及在Python编程中的运用实例
2016/06/26 Python
Python+Turtle动态绘制一棵树实例分享
2018/01/16 Python
对Python中画图时候的线类型详解
2019/07/07 Python
pytorch中nn.Conv1d的用法详解
2019/12/31 Python
Python基于内置库pytesseract实现图片验证码识别功能
2020/02/24 Python
Python和Bash结合在一起的方法
2020/11/13 Python
关于Python3的import问题(pycharm可以运行命令行import错误)
2020/11/18 Python
python中Mako库实例用法
2020/12/31 Python
梅西酒窖:Macy’s Wine Cellar
2018/01/07 全球购物
Bitiba意大利:在线宠物商店
2020/10/31 全球购物
匡威俄罗斯官网:Converse俄罗斯
2020/05/09 全球购物
销售心得体会
2014/01/02 职场文书
志愿者服务感言
2014/02/27 职场文书
主题教育活动总结
2014/05/05 职场文书
高老头读书笔记
2015/06/30 职场文书
春季运动会加油词
2015/07/18 职场文书
2016年入党心得体会范文
2016/01/23 职场文书
CSS SandBox应用场景及常见问题
2022/06/25 HTML / CSS