猫叔:Fighting!!!

JSON——《JavaScript高级程序设计》笔记

JSON (JavaScript Object Notation对象表示法)

  一种结构化数据的格式,与JavaScript有相同的语法形式,但不属于JavaScript。支持多种编程语言。

1、语法

  JSON有3种类型的值:简单值、对象 和 数组。

    简单值:字符串、数值、布尔值、null (JSON不支持JavaScript的特殊值undefined)

    对象:一组无序键值对。值可为简单值,或对象和数组。

    数组:一组有序键值对。值可为简单值,或对象和数组

  JSON不支持变量、函数 和 对象实例。

1-1、简单型

  JSON字符串必须使用双引号(单引号会导致语法错误)

1-2、对象

  JSON对象的属性必须使用双引号:

{
    "name":"xiaoming",
    "age":24
}

  与JavaScript对象字面量的区别:无声明变量;无末尾分号。

1-3、数组

  同样无声明对象;无末尾分号。

 2、解析 与 序列化

2-1、JSON对象

  早期JSON解析器使用JavaScript的eval()函数解析、解释 并 返回JavaScript对象和数组。ECMAScript5定义了全局对象JSON(支持IE8+ 等 主流浏览器)。

    eval()对JSON数据结构求值存在风险,可能会执行恶意代码,故早期浏览器可使用shim:https://github.com/douglascrockford/JSON-js

  JSON对象的两个方法:stringify()、parse()

stringify():将JavaScript对象 序列化 为JSON字符串。

 

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

var jsonText = JSON.stringify(book);

 

 

   JSON.stringify()输出的JSON字符串 默认 不包含缩进、空格符 和 换行符。

  序列化JavaScript对象时,所有函数、原型成员 和 值为undefined的属性 都会被忽略。

parse():将JSON字符串 解析 为原生JavaScript值

   传给JSON.parse()的字符串不是有效JSON时,会抛出错误。

※即使stringify()之前和parse()后 两个对象属性相同,也是两个完全独立的对象。

2-2、序列化

  JSON.stringify()有3个参数:JavaScript对象、过滤器、控制缩进等格式化

    1-过滤器(过滤结果):数组、函数

       数组过滤器:JSON.stringify()的结果 将只包含数组中列出的 属性:

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

var jsonText = JSON.stringify(book, ["title", "edition"]);

      函数过滤器:函数有2个参数,为属性(键)名 和 属性值。属性名只能为字符串,非键值对结构的键名 为空字符串。

        通过函数处理特定的属性。序列化的对象中的每个对象都要进过过滤器。

函数过滤器
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;
    }
});

返回:
{"title":"Professional JavaScript","authors":"Nicholas C. Zakas","year":5000}

        ☆实际上,第一次调用函数过滤器时,传入的是一个空字符串,值为这个book对象

    2-字符串缩进

      JSON.stringify()的第3个参数 用于控制结果的缩进和空白符。(换行符会在传入有效缩进参数时,自动添加)

        当为数值时,表示每级缩进的空格数;

        当为非数值时,做为缩进字符(不再使用空格缩进)。

      ※最大缩进数和缩进字符为10,超过时自动转换为10

View Code
var jsonText = JSON.stringify(book, null, "--");

效果:
{
----“title”: "Professional JavaScript",
----“authors”: [
--------"Nicholas C. Zakas"
----],
----“edition”: 3,
----“year”: 2011
}

    3-toJSON()方法

      toJSON()方法 可用于返回任何值;也可作为过滤器的补充,进行根精确的自定义序列化需求。

例子
var book = {
               "title": "Professional JavaScript",
                "authors": [
                    "Nicholas C. Zakas"
                ],
                edition: 3,
                year: 2011,
                toJSON: function(){
                    return this.title;
                }
           };

var jsonText = JSON.stringify(book);
alert(jsonText);

执行后将弹出消息框,内容为title属性的值:
Professional JavaScript

即toJSON()方法 会在序列化之前先执行。

☆☆☆☆☆

☆ 将一个对象传入JSON.stringify()后 的序列化 顺序:

  ①若存在 而且 能通过toJSON()获取有效值,将先调用该方法。否则返回对象本身;

  ②若存在 第2参数,将①返回的值传入 过滤器;

  ③对②返回的每个值 进行相应的序列化;

  ④若存在 第3参数,对序列化后的数据 进行相应格式化。

 2-3、解析

  JSON.parse() 2个参数:JSON对象、函数(还原函数‘reviver’,与序列化的替换函数'replacer'具有相同签名:2个参数——键与值)

    还原函数:若此函数返回undefined,将会删除相应的键,若返回其他值,则会被插入结果中。

还原函数
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());


执行后弹出消息框,内容为:2011
releaseDate属性保存着一个Date对象,序列化后,在bookCopy中又被还原成一个Date对象,故bookCopy.releaseDate才有一个Date对象,才可以调用getFullYear()方法。

 

 

 

 

posted @ 2013-04-30 01:18  庄丶大虾  阅读(3115)  评论(0编辑  收藏  举报