JSON是一种数据交换格式。
在JSON出现之前,大家一直用XML来传递数据。因为XML是一种纯文本格式,所以它适合在网络上交换数据。
XML本身不算复杂,但是,加上DTD、XSD、XPath、XSLT等一大堆复杂的规范以后,任何正常的软件开发人员碰到XML都会感觉头大了,最后大家发现,即使你努力钻研几个月,也未必搞得清楚XML的规范。
终于,在2002年的一天,道格拉斯·克罗克福特(Douglas Crockford)发明了JSON这种超轻量级的数据交换格式。道格拉斯设计的JSON实际上是JavaScript的一个子集。
一、JSON的数据类型
在JSON中,一共就这么几种数据类型:
- number:和JavaScript的
number
完全一致; - boolean:就是JavaScript的
true
或false
; - string:就是JavaScript的
string
; - null:就是JavaScript的
null
; - array:就是JavaScript的
Array
表示方式------[]
; - object:就是JavaScript的
{ ... }
表示方式。
以及上面的任意组合。
并且,JSON还定死了字符集必须是UTF-8,表示多语言就没有问题了。
为了统一解析,JSON的字符串规定必须用双引号""
,Object的键也必须用双引号""
。
由于JSON非常简单,很快就风靡Web世界,并且成为ECMA标准。几乎所有编程语言都有解析JSON的库,而在JavaScript中,我们可以直接使用JSON,因为JavaScript内置了JSON的解析。
当我们从服务器或其他来源接收到JSON格式的字符串时,通常需要将其解析为编程语言中的数据结构,以便我们可以方便地访问和操作其中的数据。这就是JSON解析的过程。
二、JSON的序列化和反序列化
把任何JavaScript对象变成JSON,就是把这个对象序列化成一个JSON格式的字符串,这样才能够通过网络传递给其他计算机。
如果我们收到一个JSON格式的字符串,只需要把它反序列化成一个JavaScript对象,就可以在JavaScript中直接使用这个对象了。
2-1、序列化
JavaScript对象------>JSON字符串
示例:把小明这个对象序列化成JSON格式的字符串
javascript
var xiaoming = {
name: '小明',
age: 14,
gender: true,
height: 1.65,
grade: null,
'middle-school': '\"W3C\" Middle School',
skills: ['JavaScript', 'Java', 'Python', 'Lisp']
};
var s = JSON.stringify(xiaoming);
console.log(s);
要输出得好看一些,可以加上参数,按缩进输出:
javascript
JSON.stringify(xiaoming, null, ' ');
第二个参数用于控制如何筛选对象的键值, 如果我们只想输出指定的属性,可以传入Array
:
javascript
var s = JSON.stringify(xiaoming, ['name', 'middle-school', 'skills'], ' ');
还可以传入一个函数,这样对象的每个键值对都会被函数先处理:
javascript
function convert(key, value) {
if (typeof value === 'string') {
return value.toUpperCase();
}
return value;
}
JSON.stringify(xiaoming, convert, ' ');
如果我们还想要精确控制如何序列化小明,可以给xiaoming
定义一个toJSON()
的方法。
在JavaScript中,如果你在一个对象内部定义了toJSON
方法,那么当该对象被序列化为JSON字符串时(例如,当你使用JSON.stringify()
方法时),toJSON
方法会被自动调用。
javascript
let person = {
name: 'John Doe',
age: 30,
gender: true,
height: 1.65,
grade: null,
'middle-school': '\"W3C\" Middle School',
skills: ['JavaScript', 'Java', 'Python', 'Lisp'],
toJSON: function() {
return {
fullName: this.name,
age: this.age
};
}
};
let jsonString = JSON.stringify(person);
console.log(jsonString); // 输出: {"fullName":"John Doe","age":30}
在这个例子中,我们定义了一个person
对象,它有一个toJSON
方法。当我们调用JSON.stringify(person)
时,toJSON
方法被调用,并返回一个新的对象,这个对象只有fullName
和age
两个属性。因此,序列化后的JSON字符串只包含这两个属性。
注意,toJSON
方法返回的值必须是能够被JSON.stringify()
序列化的。如果返回的是一个函数、undefined、或者包含循环引用的对象,那么序列化过程会失败。
2-2、反序列化
JSON字符串------>JavaScript对象
拿到一个JSON格式的字符串,我们直接用JSON.parse()
把它变成一个JavaScript对象:
javascript
JSON.parse('[1,2,3,true]'); // [1, 2, 3, true]
JSON.parse('{"name":"小明","age":14}'); // Object {name: '小明', age: 14}
JSON.parse('true'); // true
JSON.parse('123.45'); // 123.45
JSON.parse()
还可以接收一个函数,用来转换解析出的属性:
javascript
var obj = JSON.parse('{"name":"小明","age":14}', function (key, value) {
if (key === 'name') {
return value + '同学';
}
return value;
});
console.log(JSON.stringify(obj)); // {name: '小明同学', age: 14}