第22章 JSON

本文介绍了JSON作为数据交换格式的背景和优势,与XML的对比,强调了其轻量级、易读写的特点,并详细讲解了JSON的语法,包括简单值、对象和数组的表示。此外,还探讨了JSON解析和序列化的过程,以及如何优化JSON数据,以提升数据传输效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第22章 JSON

JSON是一种轻量级的、基于文本且独立于语言的数据交换格式,它比XML格式更轻巧,是XML数据格式的一种替代方案。JSON源于ECMAScript 3的子集,定义了便于表示结构化数据的一套格式规范,JSON规范符合ECMAScript语法规范,这样按JSON规范描述出的字符串已是JavaScript的原生代码,这样就可以很轻松地在JSON字符串与JavaScript对象之间进行转换。

【学习重点】

▲ 了解JSON

▲ 比较JSON和XML的结构特点

▲ 正确使用JSON数据

▲ JSON数据解析和序列化

22.1 JSON概述

XML曾经是互联网上传输结构化数据的事实标准,传统的Web服务都是建立在XML之上的,突出的特点是服务器与服务器间通信。然而,XML过于繁琐、冗长,数据访问过程复杂,浏览器兼容问题严重,业界一直声讨XML。为解决这个问题,不断涌现了一些解决方案。

2006年,Douglas Crockford把JSON(JavaScript Object Notation,JavaScript对象表示法)作为IETF RFC 4627提交给IETF,而JSON的应用早在2001年就已经开始了。JSON是JavaScript的一个子集,利用了JavaScript中的一些模式来表示结构化数据。Crockford认为与XML相比,JSON是在JavaScript中读写结构化数据的更好方式。因为可以把JSON直接传给eval(),而且不必创建DOM对象。

JSON是一种数据格式,不是一种编程语言,虽然它与JavaScript具有相同的语法形式,但JSON并不从属于JavaScript。而且,并不是只有JavaScript才使用JSON。很多编程语言都有针对JSON的解析器和序列化器。

JSON官方网站:http://www.json.org/。

JSON中文主页:http://www.json.org/json-zh.html。

22.2 比较JSON与XML

JSON是一个轻量级的数据格式,可以简化表示复杂数据结构的工作量。即使XML也能表示同样复杂的数据结果,但JSON没有那么繁琐,而且在JavaScript中使用更便利。

JSON是随Ajax应用而诞生的一种轻量级的数据格式,与XML具有相同的功能—存储、传输和交换数据。由于JSON是基于JavaScript的一个子集,因此非常容易阅读和编写。同时也易于机器解析和生成,只要熟悉JavaScript基本语法,就可以很轻松地读写JSON数据。

JSON采用完全独立于语言的文本格式,但是也采用了类似于C语法习惯,这些特性使JSON成为最理想的数据交换格式。JSON严格遵循JavaScript语法规则来组织和显示数据,因此不需要繁琐的操作就能够快速被JavaScript脚本识别。

【示例1】对于下面这个XML文档,如果想获取其中的数据,则必须先定义XML DOM对象,加载XML文档,然后再利用该对象所提供的方法和属性来遍历结构并逐一读取每个节点包含的数据,整个操作过程非常繁琐,而且还要考虑浏览器兼容性问题。

如果使用JSON数据表示,则如下所示:

直观比较,很显然JSON数据更简洁,它没有很多元素名,数据传输量当然就小很多。这仅是一个优势,更重要的是,这种格式与JavaScript语言的语法规则相一致,因此可以在JavaScript脚本中直接读取数据。

【示例2】在下面脚本中,把上面示例中JSON数据传递给变量books,此时books就是一个数组,读取第一个元素的值正好是一个对象直接量,然后以点语法读取对象中的title属性值,该属性值又是一个数组,再读取该数组的第2个元素的值,就会返回第一本书的名称:

【示例3】对于下面XML结构数据:

可以转换成JSON格式数据来表示:

其中把两组数据中相同项提取出来单独显示,这样当把它赋值给变量books之后,该变量就是一个对象变量,而不是一个数组变量,引用其中的数据如下:

     alert(books.book[0].title[1]);              //返回字符串"XPath语言基础"

上面实例演示了使用JSON格式处理数据的形式是灵活多变的。

因此,比较XML和JSON两种数据格式,具有下面几点不同。

☑ 可读性:两者都具有很强的可读性。XML数据严格遵循XML DOM模型规范,而JSON严格遵循JavaScript语法。

☑ 可扩展性:都具有超强的扩展性。XML数据通过自定义标签,可以设计更复杂的数据嵌套结构,而JSON通过数组和对象的嵌套组合也能够模拟任意XML数据结构。

☑ 编码难度:XML有丰富的编码工具(如Dom4j、JDom等),JSON也有json.org提供的工具。但是JSON编码比XML明显容易,即使不借助工具也可以手写JSON代码,但是要手写XML文档就非常困难。

☑ 解码难度:XML数据解析需要考虑结构层次,以及节点关系,解析难度大,而JSON数据不存在解析难度。

22.3 JSON语法

JSON结构可以表示以下3种类型的值。

☑ 值:使用与JavaScript相同的语法,可以在JSON中表示字符串、数值、布尔值和null,但JSON不支持JavaScript中的特殊值undefined。

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

☑ 数组:数组也是一种复杂数据类型,表示一组有序的值的列表,可以通过数值索引来访问其中的值。数组的值也可以是任意类型,如简单的值、对象或数组。

提示:JSON不支持变量、函数或对象实例,它就是一种表示结构化数据的格式,虽然与JavaScript中表示数据的某些语法相同,但它并不局限于JavaScript的范畴。

JSON数据可以由无数个对象和数组嵌套组合在一起,构成了一个完整的数据体系。

22.3.1 简单值

最简单的JSON数据形式就是简单值。例如,下面这个值是有效的JSON数据:

     1

这是JSON表示数值1的方式。类似地,下面是JSON表示字符串的方式:

     "Hello,World"

JavaScript字符串与JSON字符串的最大区别:JSON字符串必须使用双引号,不能够使用单引号,因为单引号易导致语法错误。

布尔值和null也是有效的JSON形式。但是,在实际应用中,JSON更多地用来表示更复杂的数据结构,而简单的值只是整个数据结构中的一部分。

1.字符串

字符串必须使用双引号包括起来,引号内可以包括任意数量的Unicode字符(除了字符"和\,以及控制字符外)。对于特殊字符则需要使用转义序列来表示,如表22-1所示。

表22-1 转义序列

一个字符(character)也可以称为一个单独的字符串(Character string)。

2.数值

数值可以是整数、浮点数等,也可以使用科学计数法来表示。数值可以直接引用,不需要添加引号。

3.逻辑值

逻辑值仅包括true或false,直接使用,不需要添加引号。

4.分隔符

在JSON数据中,分隔符(如空格、制表符和换行符)是不被解析的,因此可以在数据结构内任意位置增加空白,以实现对数据的格式化排版。

22.3.2 对象

对象是无序的键/值对集合。基本构成规则:以左大括号({})开始,以右括号())结束,每个键与值对之间使用冒号(:)进行分隔,键/值对之间使用逗号(,)分隔。

【示例】

     {"string1":"value1"," string 2":" value 2"," string 3":" value 3",….." string n":" value n"}

其中string为元素的名称,value为元素的值,中间使用冒号分隔。

在不同的语言中,这种数据结构有不同的名称,如对象(Object)、记录(Record)、结构(Struct)、字典(Dictionary)、哈希表(Hash Table)、有键列表(Keyed List),或者关联数组(Associative Array)。虽然名称不同,但是数据结构相同,自然也能够在不同语言之间进行交换。

提示:JSON对象与JavaScript对象直接量稍微有一些不同。下面是一个JavaScript中的对象直接量:

这是在JavaScript中创建对象直接量的标准方式。但JSON中,对象要求给属性加引号。实际上,在JavaScript中,前面的对象直接量完全可以写成下面这样:

JSON表示上述对象的方式如下:

与JavaScript的对象直接量相比,JSON对象没有声明变量,因为在JSON中没有变量的概念。另外,没有末尾的分号,因为这不是JavaScript语句,所以不需要分号。

注意:JSON对象的属性必须加双引号,这在JSON中是必需的。属性的值可以是简单值,也可以是复杂类型值,因此可以像下面这样在对象中嵌入对象:

上面例子在顶级对象中嵌入了"book"信息。虽然有两个"name"属性,但由于它们分别属于不同的对象,因此这样完全没有问题。不过,同一个对象中绝对不应该出现两个同名属性。

与JavaScript不同,JSON中对象的属性名任何时候都必须加双引号。手工编写JSON时,忘了给对象属性名加双引号或者把双引号写成单引号都是常见的错误。

22.3.3 数组

数组是有序值的集合。基本构成规则:以左中括号([)开始,以右中括号(])结束。值之间使用逗号(,)分隔。

【示例】

     ["value1"," value 2"," value 3",….." value n"]

在这个有序列表中,前后值的顺序是不能够调换的,这与大部分语言中数组功能相一致,第一个值的索引序号为0,第二个值的索引序号为1。

JSON数组采用的是JavaScript中的数组直接量形式。例如,下面是JavaScript中的数组直接量:

     var values=[1, true,"true"];

在JSON中,可以采用同样的语法表示同一个数组:

     [1, true,"true"]

注意:JSON数组也没有变量和分号。把数组和对象结合起来,可以构成更复杂的数据集合。

22.4 JSON解析和序列化

早期的JSON解析器基本上就是使用JavaScript的eval()函数。由于JSON是JavaScript语法的子集,因此eval()函数可以解析、解释并返回JavaScript对象和数组。ECMAScript 5对解析JSON的行为进行规范,定义了全局对象JSON。在旧版本的浏览器中,使用eval()对JSON数据结构求值存在风险,因为可能会执行一些恶意代码。

ECMAScript 5定义了一个原生的JSON对象,可以用来将对象序列化为JSON字符串或者将JSON数据解析为JavaScript对象。

JSON对象有两个方法:stringify()和parse()。在最简单的情况下,这两个方法分别用于把JavaScript对象序列化为JSON字符串和把JSON字符串解析为原生的JavaScript值。详细说明请参阅23.4节。

22.5 案例:优化JSON数据

JSON是一个轻量级并易于解析的数据格式,它按照JavaScript对象和数组字面语法来编写。

【示例1】下面代码是用JSON编写的用户列表。

用户为一个对象,用户列表为一个数组,与JavaScript中其他数组或对象的写法相同。这意味着如果对象被包装在一个回调函数中,JSON数据可以成为能够运行的JavaScript代码。

在JavaScript中解析JSON可简单地使用():

【示例2】上面JSON数据也可以提炼成一个更简单的版本,将名字缩短:

JSON精简版本将相同的数据以更少的结构和更小的字节尺寸传送给浏览器。

【示例3】也可以完全去掉属性名,与原格式相比,这种格式可读性更差,但更利索,文件尺寸非常小:大约只有标准JSON格式的一半。

【示例4】在解析示例3的JSON数据时,需要保持数据的顺序,也就是说,这种精简格式在进行格式转换时必须保持和第一个JSON格式一样的属性名:

在上面代码中,使用()将字符串转换为一个本地JavaScript数组,然后再将它转换为一个对象数组,用一个更复杂的解析函数换取了较小的文件尺寸和更快的时间。数组形式的JSON在每一项性能比较中均获胜,它文件尺寸最小,下载最快,平均解析时间最短。

事实上JSON可以被本地执行有几个重要的性能影响。当使用XHR时,JSON数据作为一个字符串返回。该字符串通过()转换为一个本地对象。然而,当使用动态脚本标签插入时,JSON数据被视为另一个JavaScript文件并作为本地码执行。为做到这一点,数据必须被包装在回调函数中,这就是所谓的JSON-P(JSON填充)。

【示例5】下面示例代码使用JSON-P格式编写用户列表。

因为回调包装的原因,JSON-P略微增加了文件尺寸,但是与其在解析性能上的改进相比这点增加微不足道。由于数据作为本地JavaScript处理,它的解析速度与本地JavaScript一样快。

JSON-P文件大小和下载时间与XHR测试基本相同,而解析时间几乎快了10倍。标准JSON-P的解析时间为0,因为根本用不着解析,它已经是本地格式了。简化版JSON-P和数组JSON-P也是如此,只是每种JSON-P都需要转换成标准JSON-P直接使用的格式。

最快的JSON格式是使用数组的JSON-P格式,虽然这种格式只比使用XHR的JSON略快,但是这种差异随着列表尺寸的增大而增大。如果所从事的项目需要一个由10000或100000个单元构成的列表,那么使用JSON-P比使用JSON好很多。

与XML相比,JSON有许多优点,格式小得多,在总响应报文中,结构占用的空间更小,数据占用得更多,特别是在数据包含数组而不是对象时。JSON与大多数服务器端语言的编解码库之间有着很好的互操作性。JSON在客户端的解析工作微不足道,可以将更多写代码的时间放在其他数据处理上。对网页开发者来说最重要的是,它是表现最好的格式之一,既因为在线传输相对较小,也因为解析十分之快。JSON是高性能Ajax的基石,特别是在使用动态脚本标签插入时。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值