JS红皮书读书笔记-20-JSON

TOC
  1. 1. 语法
    1. 1.1. 简单值
    2. 1.2. 对象
    3. 1.3. 数组
  2. 2. 解析与序列化
    1. 2.1. JSON对象
    2. 2.2. 序列化选项
    3. 2.3. 解析选项

在很早一段时间, XML才是WEB开发首选的数据结构, 但是JSON的出现改变了这个事实, 相比XML, JSON更加简洁, 逻辑清晰, 读取信息的时候, 也不必创建DOM对象. 所以当下JSON是web开发最流行的数据格式.

语法

JSON 的语法可以表示以下三种类型的值。

  • 简单值:使用与 JavaScript 相同的语法,可以在 JSON 中表示字符串、数值、布尔值和 null。但 JSON 不支持 JavaScript 中的特殊值 undefined。
  • 对象:对象作为一种复杂数据类型,表示的是一组无序的键值对儿。而每个键值对儿中的值可 以是简单值,也可以是复杂数据类型的值。
  • 数组:数组也是一种复杂数据类型,表示一组有序的值的列表,可以通过数值索引来访问其中 的值。数组的值也可以是任意类型 简单值、对象或数组。

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

简单值

数值/布尔值/字符串/null 四种

对象

JSON对象和JS对象字面量稍有不同, JSON对象的字段, 必须并且只能用双引号括起来.

这个是JS对象字面量:

var obj = {
name: 'testdog',
age: 18
}

这个是JSON对象:

{
"name": "testdog",
"age": 18,
"school":{
"name":"ABC",
"addr":"China"
}
}

JSON是不能有注释的, 最后的字段末尾不能有逗号

数组

略, 语法注意事项同上

解析与序列化

JSON对象

JSON 之所以流行,拥有与 JavaScript 类似的语法并不是全部原因。更重要的一个原因是,可以把JSON 数据结构解析为有用的 JavaScript 对象。与 XML 数据结构要解析成 DOM 文档而且从中提取数据极为麻烦相比,JSON 可以解析为 JavaScript 对象的优势极其明显。
早期的 JSON 解析器基本上就是使用 JavaScript 的 eval()函数。由于 JSON 是 JavaScript 语法的子集,因此 eval()函数可以解析、解释并返回 JavaScript 对象和数组。对于较早版本的浏览器,可以使用一个 shim:https://github.com/douglascrockford/JSON-js。在旧版本的浏览器中,使用 eval()对 JSON 数据结构求值存在风险,因为可能会执行一些恶意代码。对于不能原生支持 JSON 解析的浏览器,使用这个 shim 是最佳选择。

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

例如: 将js对象转化成JSON字符串

var book = {
title: "Professional JavaScript",
authors: [
"Nicholas C. Zakas"
],
edition: 3,
year: 2011
};

var jsonText = JSON.stringify(book);

默认情况下,JSON.stringify()输出的 JSON 字符串不包含任何空格字符或缩进,因此保存在 jsonText 中的字符串如下所示:

{"title":"Professional JavaScript","authors":["Nicholas C. Zakas"],"edition":3, "year":2011}
```
在序列化 JavaScript 对象时,所有函数及原型成员都会被有意忽略,不体现在结果中。此外,值为undefined 的任何属性也都会被跳过。结果中最终都是值为有效 JSON 数据类型的实例属性。

将 JSON 字符串直接传递给 JSON.parse()就可以得到相应的 JavaScript 值。例如,使用下列代码就可以创建与 book 类似的对象:
``` js
var bookCopy = JSON.parse(jsonText);

注意,虽然 book 与 bookCopy 具有相同的属性,但它们是两个独立的、没有任何关系的对象。如果传给 JSON.parse()的字符串不是有效的 JSON,该方法会抛出错误。

序列化选项

JSON.stringify一共有三个参数:

var book = {
"title": "Professional JavaScript", "authors": [
"Nicholas C. Zakas"
],
edition: 3,
year: 2011
};

// 第一个参数自然是要被序列化的对象, 第二个参数可以是一个数组或者说函数,第三个参数是一个缩进选项

var jsonText = JSON.stringify(book, ["title", "edition"]);//这里的第二个参数是一个数组, 代表一个过滤器, 返回 {"title":"Professional JavaScript","edition":3}

// 这里的第二个参数是一个函数
var jsonText2 = JSON.stringify(book, function(key, value){
switch(key){
case "authors":
return value.join(",")

case "year":
return 5000;

case "edition":
return undefined;

default:
return value;
}
});

// jsonText2返回: {"title":"Professional JavaScript","authors":"Nicholas C. Zakas","year":5000} , 注意这里是没有"edition"这个字段, 因为它值为undefined, 被过滤了.

var jsonText3 = JSON.stringify(book, null, 4);
//jsonText3返回的格式缩进就带4个空格

还有一个补充JSON.stringify的方法, toJSON, 讲解略.

解析选项

JSON.parse()方法也可以接收另一个参数,该参数是一个函数,将在每个键值对儿上调用。为了区别 JSON.stringify()接收的替换(过滤)函数(replacer),这个函数被称为还原函数(reviver),但实际上这两个函数的签名是相同的 它们都接收两个参数,一个键和一个值,而且都需要返回一个值。

如果还原函数返回 undefined,则表示要从结果中删除相应的键;如果返回其他值,则将该值插入到结果中。在将H期字符串转换为 Date 对象时,经常要用到还原函数。例如:

var book = {
"title": "Professional JavaScript", "authors": [
"Nicholas C. Zakas"
],
edition: 3,
year: 2011,
releaseDate: new Date(2011, 11, 1)
};

var jsonText = JSON.stringify(book);

var bookCopy = JSON.parse(jsonText, function(key, value){
if (key == "releaseDate"){
return new Date(value);
} else {
return value;
}
});

alert(bookCopy.releaseDate.getFullYear());

本章完

访客评论