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 相关文章推荐
下载网站打开页面后间隔多少时间才显示下载链接地址的代码
Apr 25 Javascript
jquery实现导航固定顶部的效果仿蘑菇街
Oct 22 Javascript
JavaScript中实现继承的三种方式和实例
Jan 29 Javascript
js实现点击链接后延迟3秒再跳转的方法
Jun 05 Javascript
jquery实现表单获取短信验证码代码
Mar 13 Javascript
详解解决使用axios发送json后台接收不到的问题
Jun 27 Javascript
jQuery实现基本动画效果的方法详解
Sep 06 jQuery
使用ECharts实现状态区间图
Oct 25 Javascript
vue 详情跳转至列表页实现列表页缓存
Mar 27 Javascript
vue实现axios图片上传功能
Aug 20 Javascript
React传值 组件传值 之间的关系详解
Aug 26 Javascript
vue实现购物车小案例
Sep 27 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
ajax+php打造进度条代码[readyState各状态说明]
2010/04/12 PHP
php截取视频指定帧为图片
2016/05/16 PHP
PHP链表操作简单示例
2016/10/15 PHP
php利用fsockopen GET/POST提交表单及上传文件
2017/05/22 PHP
PHP文件管理之实现网盘及压缩包的功能操作
2017/09/20 PHP
阿里云的WindowsServer2016上部署php+apache
2018/07/17 PHP
javascript &&和||运算法的另类使用技巧
2009/11/28 Javascript
JavaScript的类型转换(字符转数字 数字转字符)
2010/08/30 Javascript
fancybox1.3.1 基于Jquery的插件在IE中图片显示问题
2010/10/01 Javascript
window.name代替cookie的实现代码
2010/11/28 Javascript
学习使用bootstrap3栅格系统
2016/04/12 Javascript
Bootstrap Modal遮罩弹出层(完整版)
2016/11/21 Javascript
javascript 的变量、作用域和内存问题
2017/04/19 Javascript
vue.js 上传图片实例代码
2017/06/22 Javascript
Vue 路由 过渡动效 数据获取方法
2018/07/31 Javascript
Layui组件Table绑定行点击事件和获取行数据的方法
2018/08/19 Javascript
浅谈从React渲染流程分析Diff算法
2018/09/08 Javascript
浅析微信扫码登录原理(小结)
2018/10/29 Javascript
Node.js fs模块原理及常见用途
2020/10/22 Javascript
Python Web框架Flask中使用七牛云存储实例
2015/02/08 Python
用python找出那些被“标记”的照片
2017/04/20 Python
python 利用文件锁单例执行脚本的方法
2019/02/19 Python
利用python实现冒泡排序算法实例代码
2019/12/01 Python
Python文件时间操作步骤代码详解
2020/04/13 Python
python 瀑布线指标编写实例
2020/06/03 Python
HTML5地理定位_动力节点Java学院整理
2017/07/12 HTML / CSS
IFCHIC台湾:欧美国际设计师品牌
2019/05/18 全球购物
优秀共产党员先进事迹
2014/01/27 职场文书
校园十大歌手策划书
2014/02/01 职场文书
开门红主持词
2014/04/02 职场文书
2014年预算员工作总结
2014/12/05 职场文书
2014年居委会工作总结
2014/12/09 职场文书
《认识年月日》教学反思
2016/02/19 职场文书
Python中的套接字编程是什么?
2021/06/21 Python
关于PHP数组迭代器的使用方法实例
2021/11/17 PHP
WINDOWS 64位 下安装配置mysql8.0.25最详细的教程
2022/03/22 MySQL