zoukankan      html  css  js  c++  java
  • JSON序列化与反序列化

    一、序列化与反序列化的概念

    序列化(Serialization):将数据结构或是对象 转换为 二进制串(字节序列)的过程

    反序列化:将二进制串(字节序列)转换为 数据结构或者对象 的过程

    序列化 就是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区(如硬盘)。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。

    二、对象序列化的用途目的:

    1、把对象的字节序列永久保存在硬盘上(以某种储存方式使自定义对象持久化);

    2、在网络上传送对象的二进制序列(将对象从一个地方传递到另一个地方);

    3、使程序更具维护性。

    三、解析与序列化

    早期的JSON解析器使用的是JavaScript函数的eval( ) 函数。由于JSON是JS语法的子集,所以eval()函数可以解析、解释并返回JS对象和数组。

    由于在一些较早版本的浏览器,使用eval()对JSON数据结构存在风险,可能会产生一些恶意代码,所以现在不再经常使用这个函数。

    JSON对象有两个方法:(在最简单的情况下)

    JSON.stringify() 把JavaScript对象序列转换为JSON字符串;

    JSON.parse() 将JSON字符串解析为原生Javascript对象;

    实例:

    在这个例子中使用JSON.stringify( ) 把JavaScript对象序列转换为一个JSON字符串

    然后将其保存在jsonText变量中,并使用document.write( ) 函数使结果在页面输出。

    var person= { 
                   "name":"张三",
               "address":["中国","河北"],
               "age":"20",
            "gender":"男" ,
               "birth":"1999"
        };
        var jsonText = JSON.stringify(person);
    document.write(jsonText);

    显示结果

    注意:在序列化JavaScript对象时,所有的函数及原形成员都会被有意忽略,默认情况下JSON.stringify()输出的JSON字符串不包含任何空格字符或缩进;,不体现在结果中。此外,值为Undefined的任何属性也都会被跳过。最终结果中都是值为有效JSON数据类型的实例属性。

    2、将JSON字符串直接传递给JSON.parse( ) 就可以得到相应的JavaScript值

    例如,使用以下代码就会创建于person类似的对象。

     注意:虽然person和persoinf 具有相同的属性,但是它们是两个独立的、没有任何关系的对象。如果传递给 JSON.parse()不是有效的JSON,该方法就会出错

    四、序列化选项

    实际上,JSON.stringify()除了要序列化的javascript对象之外,还可以接收两个参数,这两个参数可以用于指定以不同方式序列化的JavaScript

    1、第一个参数是过滤器(可为数组或函数

    2、第二个参数是一个选项(表示是否在JSON字符串中保留缩进

     

    (一)过滤结果

    1、如果过滤器的参数是数组那么JSON.stringify( ) 的结果中将只包含数组中列出的属性

    例如:

    var person= { 
                   "name":"张三 李四",
               "address":["中国","河北"],
               "age":20,
            "gender":"男" ,
               "birth":"1999"
        };
        var jsonText = JSON.stringify(person,["name","age"]);
        document.write(jsonText);

    JSON.stringify( ) 的第一个参数是变量名称,第二个参数是一个数组,其中包含两个字符串:"name" 和 "age" 。这两个属性与将要序列化的对象中的属性是对应的,因此在返回结果的字符串中就会包含这两个属性:

    2、如果第二个参数是函数,行为会稍有些不同。传入的函数接受两个参数,属性(键)名和属性值。根据属性名(键)可以知道应该如何处理要序列化的对象的属性。

    属性名只能是字符串,而在值并非键值对结构的值时,键名可以是空字符串。

    为了改变序列化对象的结果,函数返回的值就是相应键的值。

    注意:如果函数返回了undefined,那么相应的属性会被忽略

    var person= { 
                   "name":"张三",
               "address":["中国 河北"],
               "age":20,
            "gender":"男" ,
               "birth":1999
        };
        var jsonText = JSON.stringify(person, function(key, value) {
            switch(key){
                case "address":
                    return value.join(",")
                case "birth":
                    return 2000;
                case "age":
                    return undefined;
                default:
                    return value;
            }
        });
        document.write(jsonText);

    函数过滤器根据传入的键来决定结果。

    如果键(属性名)为 "adress",则将数组连接为一个字符串;

    如果键为 "birth",则将其值设置为2000;

    如果键为 "age",通过返回undefined来删除该属性。

    最后,一定要提供default项,此时返回传入的值,以便其他的值都可以正常出现在结果中。实际上,第一次调用这个函数过滤器,传入的键是一个空字符串,而值就是person 对象。

    序列化后的字符串如下所示:

    要序列化的对象中每一个对象都要经过过滤器,因此数组中的每个带都有这些属性的对象经过过滤器之后,每个对象都会包含"name"、"address"、"gender"、"birth" 属性。

     

    (二)字符串缩进

    JSON.stringify() 方法的第三个参数用于控制结果中的缩进和空白字符。

    如果这个参数是一个数值,那他表示的是每个级别缩进的空格数。

    实例:

    1、要在每个级别中缩进5个空格

    var person= { 
                   "name":"张三",
               "address":["中国 河北"],
               "age":20,
            "gender":"男" ,
               "birth":1999
        };
        var jsonText = JSON.stringify(person, null,5);
        document.write(jsonText);

    保存在jsonText中的字符串如下:

    注意:JSON.stringify()也在结果字符中穿插了换行符以提高可读性。只要传入有效的控制缩进的参数值。最大缩进空格数为10,所有大于10的值都会自动转换为10。

    2、如果缩进参数是一个字符串而并非数值,则这个字符串将在JSON中被用作缩进符(不再使用空格)。

    在使用字符串的情况下,可以将缩进字符设置为制表符,或是两个短线之类任意字符。

    注意:缩进符最长不超过10个字符。如果超过了10个字符长,结果中就会只显示出前10个的字符

     

     

     

    (三)toJSON( ) 方法

    有时候JSON.stringify() 方法不能满足对某些对象自定义序列化的需求。

    这时,可以给对象定义toJSON( ) 方法,返回其自身的JSON数据格式

    原生Date对象有一个toJSON()方法,能将JavaScript的Date对象自动转换为ISO 8601日期字符串(与在Date对象上调用toISOString()的结果完全一样)

    可以为任何对象添加  toJSON( ) 方法。

    实例:

    var person= { 
                   "name":"张三",
               "address":["中国 河北"],
               "age":20,
            "gender":"男" ,
               "birth":1999,
               toJSON: function(){
                   return person.address;
                   // return this.address;
               }
        };
        var jsonText = JSON.stringify(person);
        console.log(jsonText);

    person对象上定义了一个toJSON( ) 方法,该方法返回 person 的 address 地址。这个对象可以被序列化为一个简单的字符串而非对象。

    可以让toJSON()方法返回任何值,都可以正常工作。

    假设,想让方法返回 undefined ,此时如果包含它的对象嵌套在另一个对象中,会导致它的值变成null,如果是顶级对象,则结果就是undefined。

     

    (四)序列化对象的顺序

     假设把一个对象传入JSON.stringify( )序列化该对象的顺序如下

    1、如果存在 toJSON( ) 方法并且可以通过方法获得有效的值,则调用该方法,否则返回对象本身;

    2、如果提供了第二个参数,应用这个函数过渡器。传入函数过渡器的值是第一步返回的值;

    3、对第二步返回的每个值进行相应的序列化;

    4、如果提供了第三个函数,执行相应的格式化;

    无论是考虑定义toJSON( ) 方法,还是使用函数过滤器,又或者是同时使用着两种方法,理清顺序都是非常重要的。

    五、解析选项

     JSON.parse( ) 方法也可以接收另一个参数,该参数是一个函数,将在每个键值对上调用——还原函数

    为了区别JSON.stringify()接收的替换(过渡)函数(replacer),这个函数被称之为还原函数(reviver)

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

    实例:

    var person= { 
                   "name":"张三",
               "address":["中国 河北"],
               "age":20,
            "gender":"男" ,
               "birth":1999,
               "releaseDate":new Date(2019, 9, 29)    
        };
        var jsonText = JSON.stringify(person);
        var jsonCopy = JSON.parse(jsonText, function(key, value){
            if (key == "releaseDate") {
                return new Date(value);
            } 
            else{
                reture value;
            }
        });
        console.log(jsonCopy.releaseDate.getFullYear());

          在这个例子中,先是为person对象增加了一个releaseDate属性,该属性又保存了一个Date对象。

    这个对象经过序列化之后变成了有效的JSON字符串,然后经过解析又在jsonCopy中还原为一个Date对象。

    还原数据在遇到 "releaseDate" 键时,会基于相应的值创造一个新的Date对象。

    结果就是jsonCopy.releaseDate 属性中会保存一个Date 对象。正因为如此,才能基于这个对象调动 getFullYear( ) 方法。

  • 相关阅读:
    JVM系列五:JVM监测&工具[整理中]
    Washing Text Animation
    Cloth
    藤条生长为字母的动画
    音频驱动曲线
    Wood Chipping Text Animation
    融化的文字
    流体文本动画
    Blender Tutorial
    UV纹理+修改器:VertexWeightEdit+修改器:Mask遮罩
  • 原文地址:https://www.cnblogs.com/nyw1983/p/11605241.html
Copyright © 2011-2022 走看看