JSON 格式数据的定义及操作

JSON —— JavaScript Object Notation,JavaScript对象表示法

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

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

1、在表示“简单值”数据形式时, JSON 字符串必须使用双引号(单引号会导致语法错误),这是JavaScript 字符串与 JSON 字符串的最大区别。

2、在表示“对象”数据形式时,与 JavaScript 的对象字面量相比, JSON 对象有两个地方不一样。首先,没有声明变量(JSON 中没有变量的概念)。其次,没有末尾的分号(因为这不是 JavaScript 语句,所以不需要分号)。在 JSON 中,对象的属性必须加双引号,这是必需的。属性的值可以是简单值,也可以是复杂类型值。

// javaScript 对象字面量,属性的双引号可省略
var object = {
    "name": "Nicholas",
    "age": 29
};
// 而用JSON格式表示上面的对象如下
{
    "name": "Nicholas",
    "age": 29
}
// JSON格式的属性值可以为简单值,也可以为复杂值
{
    "name": "Nicholas",
    "age": 29,
    "school": {
        "name": "Merrimack College",
        "location": "North Andover, MA"
    }
}

3、在表示“数组”数据形式时, JSON 数组采用的就是 JavaScript 中的数组字面量形式。同样要注意, JSON 数组也没有变量和分号。

// 下面是 JavaScript 中的数组字面量:
var values = [25, "hi", true];
// 在 JSON 中,可以采用同样的语法表示同一个数组:
[25, "hi", true]

把数组和对象结合起来,可以构成更复杂的数据集合,如下:

[
    {
        "title": "Professional JavaScript",
        "authors": [
                "Nicholas C. Zakas"
            ],
        "edition": 3,
        "year": 2011
    },
    {
        "title": "Professional JavaScript",
        "authors": [
                "Nicholas C. Zakas"
            ],
        "edition": 2,
        "year": 2009
    },
    {
        "title": "Professional Ajax",
        "authors": [
                "Nicholas C. Zakas",
                "Jeremy McPeak",
                "Joe Fawcett"
            ],
        "edition": 2,
        "year": 2008
    }
]

对象和数组通常是 JSON 数据结构的最外层形式(当然,这不是强制规定的),利用它们能够创造出各种各样的数据结构。

JSON 之所以流行,拥有与 JavaScript 类似的语法并不是全部原因。更重要的一个原因是,可以把JSON 数据结构解析为有用的 JavaScript 对象。

相关方法:

JSON 对象有两个方法: stringify()和 parse()。
JSON.parse()解析: JSON 字符串 => javaScript 对象
JSON.stringify()序列化:javaScript 对象 => JSON 字符串

1、JSON.stringify()序列化

在序列化 JavaScript 对象时,所有函数及原型成员都会被有意忽略,不体现在结果中。此外,值为undefined 的任何属性也都会被跳过。结果中最终都是值为有效 JSON 数据类型的实例属性。

// JSON.stringify()序列化,把一个 JavaScript 对象序列化为一个 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}*/

默认情况下, JSON.stringify()输出的 JSON 字符串不包含任何空格字符或缩进。 JSON.stringify()还有第二个参数(用于过滤要序列化的数据,可以是一个数组,也可以是一个函数)和第三个参数(定义空格的个数,最多为10;或者使用字符来间隔数据)

var book = {
    "title": "Professional JavaScript",
    "authors": [
        "Nicholas C. Zakas"
    ],
    edition: 3,
    year: 2011
};
var jsonText = JSON.stringify(book, function(key, value){
    switch(key){
        case "authors":
            return value.join(",")
        case "year":
            return 5000;
        case "edition":
            return undefined;
        default:
            return value;
    }
}, 2);

2、JSON.parse()解析

如果传给 JSON.parse()的字符串不是有效的 JSON,该方法会抛出错误。

// JSON.parse()解析,把一个 JSON 字符串 解析为一个 JavaScript 对象
var bookCopy = JSON.parse(jsonText);

JSON.parse() 也可以接收第二个参数(该参数是一个函数,有key和value两个传参),为了区别 JSON.stringify()接收的替换(过滤)函数(replacer),这个函数被称为还原函数(reviver),但实际上这两个函数的签名是相同的——它们都接收两个参数,一个键和一个值,而且都需要返回一个值。

如果还原函数返回 undefined,则表示要从结果中删除相应的键;如果返回其他值,则将该值插入到结果中。

// 在将日期字符串转换为 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;
    }
});
console.info(bookCopy.releaseDate.getFullYear());

/* 以上代码先是为 book 对象新增了一个 releaseDate 属性,该属性保存着一个 Date 对象。这个对象在经过序列化之后变成了有效的 
JSON 字符串,然后经过解析又在 bookCopy 中还原为一个 Date对象。还原函数在遇到"releaseDate"键时,会基于相应的值创建一个
新的 Date 对象。结果就是bookCopy.releaseDate 属性中会保存一个 Date 对象。正因为如此,才能基于这个对象调用getFullYear()方法。*/

在旧版本的浏览器中,使用 eval()对 JSON 数据结构求值存在风险,因为可能会执行一些恶意代码。
对于不能原生支持 JSON 解析的浏览器,使用这个 shim 是最佳选择。
JSON在低版本(IE8以下)中上面两个方法不能用,可以加入hack方法shim来使用。shim

你可能感兴趣的:(javascript)