有些东西在日常的工作中会经常的用到,有可能天天见到,但是却总是没法引起注意。当需要修改这些东西的时候,一个奇怪的感觉便出现了,那就是自己似乎很了解这些东西,但好像又知之甚少,JSON便是这其中之一。

JSON是个啥?

JSON的全称是JavaScript Object Notation,即JavaScript对象表示法,从名字不难看出,JSON和JS家族关系颇深,而实际上也却确实如此。JSON本身便是作为ECMAScript的子集诞生的,其本身的格式可以通过JavaScript的eval()函数直接读取。

由于JavaScript的独特应用场景,JSON便在网络这一块大放异彩。我们常说市场决定发展,本世纪以来互联网相关内容激增,使得JSON运用的场景也不仅仅局限于ECMAScript,而是早已渗透了网络开发的方方面面。

姑且先褪去时代浪潮赋予其的铅华,我们先来看一下JSON的工作。简而言之,JSON所要负责的便是存储与交换数据。对JS或其他与网络相关开发有所了解的人应该能体会到这句话的分量,在我们日常访问网站的时候,不单单只是获取一些页面元素那么简单,很多时候还需要进行一些数据的交换通信,不单单是访问者与服务器间的通信,服务器之间也需要频繁的访问。而尽管我们有了TCP/IP协议,HTTP通讯协议也规定了POST和GET之类的方法,但这些都停留在数据的传输上,它们所解决的问题只是如何将A的东西发送给B,但是,A所说的一些话即使B能够听到了,也存在着B听不懂的可能。互联网开发的语言丰富多彩,Developers也有千千万,每个人都有各自的习惯,我可以令A←1是一种数据存储的表达,也可以令A=1是一种数据存储的表达,但显然,这两种方式难以互相识别。这时,数据的定义就需要一个好的标准,否则若是各家自立门户,势必造成一个混乱的局面。这便是JSON的工作,如果查看菜鸟教程中有关JSON的介绍就会发现有这么一句:

JSON 独立于语言:JSON 使用 JavaScript语法来描述数据对象,但是 JSON 仍然独立于语言和平台。JSON 解析器和 JSON 库支持许多不同的编程语言。 目前非常多的动态(PHP,JSP,.NET)编程语言都支持JSON。

这一个特性便是解释了上一大段的情况——一个独立编程语言定义了数据表达方式的方法

不是已经有XML了吗?

说到这里,可能会使人想起了XML这个老朋友。的确,在W3School的关于XML的介绍中便提到了XML也是用来结构化文档和数据的全新格式。

诚然,二者在其功能上有很大的交集,但是其自身的特性却又决定了各自与众不同的运用场景。XML更强调于内容的严谨,如果查看XML的教程,可能会快就被其严格的要求所震慑到,像是命名规则、父子元素关系、属性拓展等等,也正是这些特性使得其在一些很严谨的应用场合得到了很大的利用,例如数学、音乐、化学这些专门的领域,甚至一些软件的配置文件也会采用XML来定义。

而JSON似乎出生便带着自身年轻的特点。比起继承于HTML这个93年就定义了草案的XML,01年才开始推广,到05、06年伴随着互联网兴起而出名的JSON则将简洁发挥至极。

若简要介绍JSON的语法,那就是键:值这个常见的类型。你甚至可以整个内容都只需呀这样表达:

{key1:value1,key2:value2}

仅需要在你要表达的数据前后加上花括号以标志,你的一个JSON对象就已经定义结束了,而在XML,则严格要求你使用树结构,并且含有一个根元素,而数据内容则需要作为其子元素。这样,上面的数据以XML则需要这样表达:

<root>
    <key1>value1</key1>
    <key2>value2</key2>
</root>

姑且不谈多增加的根元素表达,仅仅是单一数据的表达,还需要增添一个闭合标签</tag>,对于较长的键名,可能整整多出一倍的数据量。若仅仅是个位数的数据来讲,还无法看出差距,但当数据增添到成百上千个,那么需要传递的数据量可能会成倍增加。虽然以目前的互联网传输速率,这些新增的十几几十Kbit数据量还不够一些图片,但考虑到跨境访问时的情况,内容的压缩依然是一个重要的内容。

JSON的语法

如果只是想了解一下JSON,那么上面的一千多字的小作文已经基本可以满足你的好奇心了。但如果还想进一步了解如何写一个JSON,那么就还请继续向下阅读。

首先我们需要明确一点,一个有效的JSON文档只允许两种类型作为存在,一种是对象,另一种便是数组。这有点类似于XML的根元素,但是又不尽然。因为JSON文档中的这个根其实是作为JSON的数据类型而定义的。

JSON包含六种基本的数据类型,分别为:数值、字符串、布尔、数组、对象、空值。除了数组和对象外,其余四种类型的定义方式都是以键:值来定义。而JSON的键名则需要被一组双引号所包裹,也就是以字符串的形式出现。因而这四种类型的定义方式应该如下:

"name":123
"name":"string"
"name":false
"name":null

以上的四种数据类型的定义模式,结合对象和数组的使用,便构成了完整的JSON。

对象的定义则是在花括号{}中再定义其他的数据,例如:

{
    "name1":123,
    "name2":"string",
    "name3":false,
    "name4":null,
    "name5":["value1","value2","value3"]
}

JSON不需要缩进与空格,上面的书写格式完全可以转化为无空格的单行格式,这样写仅仅是便于人类阅读。

除了作为文档的根,对象也可以作为数据中的数值,因而可以有一下的定义方式:

"father":{"child1":"value1","child2":"value2"}

像这样,father就被定义为了一个对象

如果细心的话,你可以发现上面的代码中逗号,的使用很有讲究。如果用一句话来概括逗号使用的话,那便是“同级别数据间使用,同级别的最后一个键值数值末尾不需要”。观察上例,name 1、2、3、4、5这几个之间是同级别的数据,因而1与2、2与3、3与4、4与5之间有逗号分隔,而name5是同级别中最后一个数据,因而name5后面没有逗号;同理,value1、2、3也遵循此规则。

同样的,数组和对象也有类似的用法。作为可以将数据定义在其内,例如:

[
    {"key1":val1,"key2":val2},
    {"key3":val3},
    {"key4":[val4,val5]},
    "val6",
    7,
    ["val8","val9",10]
]

同样,数组也可以作为数据的数值,如:

{"key":["val1",123,true,null,{"k2":123}]}

此外,对象和数组之间可以互相嵌套(禁止套娃)而这样的写法也较为常见,例如一个典型的npm的package列表就是对象的嵌套,如:

{
    "private": true,
    "scripts": {
        "dev": "npm run development",
        "development": "mix",
        "watch": "mix watch",
        "watch-poll": "mix watch -- --watch-options-poll=1000",
        "hot": "mix watch --hot",
        "prod": "npm run production",
        "production": "mix --production"
    },
    "devDependencies": {
        "axios": "^0.21",
        "jquery": "^3.2",
        "laravel-mix": "^6.0.6",
        "lodash": "^4.17.19",
        "resolve-url-loader": "^4.0.0",
        "sass": "^1.15.2",
        "sass-loader": "^12.1.0"
    }
}

同样的,也可以在数组中进行类似的嵌套,亦可以两者相互嵌套,对于接收方来讲,差别只不过是这个总体的数据是一个对象还是数组罢了

当能够彻底理解数组、对象以及逗号的用法的时候,JSON就已经完全被你理解了,剩下的就是如何在其他语言中实现对其的运用了!


JSON的简介与教程
https://Mundnaity.moe/post/JSON-Introduction
作者
Mundanity Fan
发布于
2021-09-19
许可协议