JSON--解析与序列化

来源:互联网 发布:专利运营知乎 编辑:程序博客网 时间:2024/05/21 22:56

    JSON之所以受到广大的程序员欢迎的原因不仅仅是拥有与javascript类似的语法,更重要的是因为可以把JSON数据结构解析为游泳的javascript对象。相对于JSON数据结构来说,XML是需要解析成DOM文档而且从中提取数据,这样子就会过于繁琐。所以JSON可以解析为javascript对象的优势就极其的明显。

    JSON对象

    根据资料,早期的JSON解析器基本上就是使用javascript的eval()函数。由于JSON是javascript语法的子集,因此eval()函数可以解析,解释并返回javascript对象和数组。但是后来对解析JSON的行为进行了规范,定义了全局的对象JSON。支持这个对象的浏览器有IE8+,Firefox 3.5+...这个对象有两个方法:stringify()和parse()。在最简单的情况下,这两个方法可以把javascript对象序列化为JSON字符串和把JSON字符串解析为原生的javascript值。

    为了更好地理解这些概念,这里举出一些例子:

var book={   //javascript 中的对象的表示方法。

"name":"ben",

"sex":"men",

"age":29

}


var bookCopy=JSON.stringify(book);

得到的结果是:

{"name":"ben","sex":"men","age":29}

    可以明显地看出,我们运用JSON.stringify()序列化javascript对象为JSON字符串的时候,得到的字符串中没有了空格而且也忽略了缩进,这个是默认情况下生成出来的运行结果。同时,还有一个需要注意的是在序列化javascript对象的时候,所有的函数以及原型成员都会被有意地忽略,不会再运行的结果中出现的。而且如果返回的值是undefined的话,也该属性将会被跳过的。结果中最终都是JSON中有效的数据类型的实例属性。

    还有一个地方需要注意的是,我们还可以通过JSON.parse()方法来对JSON字符串进行解析:var book1=JSON.parse(bookCopy),这里需要清楚的一点就是,这里的是运行了JSON.parse()将JSON字符串解析为javascript的对象值,虽然book1是javascript的对象,但是它与前一个book并不是同一个对象,即使他们是拥有相同的属性,但是他们独立,没有任何关系的两个对象。而且如果JSON.parse()中传递进去的字符串如果不是有效的JSON字符串,则还是会出现错误的。


      序列化

     接下来我们将详细讲解关于序列化选项。刚刚我们使用的JSON.stringify(),只对它传递了一个参数,实际上它还可以另外接受两个参数,这两个参数用于指定以不同的方式序列化javascript对象。第一个参数是一个过滤器,可以是一个数组,也可以是一个函数。第二个选项是表示是否在JSON字符串中保留缩进。

1.过滤结果(假如我们在第一个参数中添加一个数组),其中包含两个字符串"title""edtion"。这两个属性与将要序列化的对象中的属性石对应的,则返回到结果字符串中,就只会包含这两个属性。

如果第二个参数是函数的话,行为会有点不同,传入的函数中接受的是两个字符串,包括键名和值。根据属性键名就可以知道应该如何处理序列化的对象中的属性,属性名只能是字符串,而且在非键值对结果的值,键名可以是空的紫福春。为了改变序列化对象中的结果,函数返回值就是响应的键值。但是如果函数返回了undefined,那么相应的属性就会被忽略,。


2.字符串缩进,就如我们之前知道,将javascript对象序列化为JSON字符串的时候,空格和缩进是不存在的,而第三个参数就是用来控制结果中的缩进和空白符。如果这个参数是一个数值,那它表示的每个级别的缩进的空格数,例如要在每个级别缩进4个空格。

var jsonText=JSON.stringify(book,null,4);

    有一个比较特别的就是当我们设置了缩进的参数值之后,结果的字符集就会自动包含换行符,最大缩进空格数为10,如果大于10 的话,也会自动转换为10.

    同时我们还可以使用字符串而不是数值来进行缩进,这样子的话,缩进的符号就不是空格,而是字符串。


3.toJSON()方法

如果JSON.stringify()还是不能满足某些对象进行自定义序列化的需求,在这些情况下,可以给对象定义toJSON()方法,返回其自身的JSON数据格式。

加入以下是javascript对象的表示方法:

var person={

“name”:"ben",

"sex":"men",

"age":29

toJSON:function(){

return this.name;

}

};

var jsonText=JSON.stringify(book);

    那么这段代码运行出来的结果就是"ben".

    toJSON()可以返回任何值,它都能正常工作,而且我们注意到的是,输出的结果只有ben ,而其他的属性sex,age等等都是没有输出来,因为在该javascript对象中我们使用了toJSON对象,过滤了其他的属性,只剩下name这个属性,所以JSON.stringify(book),传进来的数据时toJSON函数中返回来的数据。

    所以我们就来看一下序列化该对象的顺序:

1)如果存在toJSON对象的话,而且它能够返回有效的JSON数据类型,那么就调用该方法。

2)如果提供了第二个参数是一个函数过滤器的话,传入函数过滤器的值是第一步返回的值。这里需要注意的是,如果第二个参数是数组过滤器的话,则数组过滤器不起作用。

3)对第2步返回的每一个值进行相应的序列化。

4)如果有第三个参数的话,执行相应的格式化。


    解析选项

    JSON.parse()方法也可以接受另一个参数,该参数是一个函数,将在每个键值对上调用。为了区别JSON.stringify()中第二个参数中的过滤函数,这个函数成为还原函数(其实就是将JSON字符串解析为javascript对象,相当于是一个还原的过程),但是实际上这两个函数的签名是相同的,他们都接受两个参数,一个键和一个值,而且都是需要返回一个值。

    同时如果还原函数返回的是undefined的话,还是要从结果中删除相应的键。如果返回其他的值得话,就插入到该结果中。

这里的例子是参照书上的例子:将日期子妇产转换为Date对象的时候,就需要使用到还原函数。

var  book={

    "title":"Professional",
    "authors":["Nicholas"],
    "edition":3,
    "year":2011,
   release: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.realseDate.getFullYear());

这里就是还原一个Date对象。







原创粉丝点击