美文网首页
JSON.stringify详解

JSON.stringify详解

作者: EickL | 来源:发表于2019-06-08 21:00 被阅读0次

    当我们使用JSON.stringify()序列化一个值为JSON字符串,只有JSON安全的值才可以通过JSON.stringify() 转换为字符串。那么,什么是JSON安全的值?能够有效用JSON形式表示的任何值。

    非JSON安全的值,例如:undefinedfunctionsymbol以及循环引用的object(对象结构的属性引用通过创建彼此,构成一个无限循环)。对一个标准的JSON结构来说,这些值都是非法的,主要是因为它们无法移值到其他支持JSON的语言中。

    JSON.stringify()遇到undefinedfunctionsymbol的时候,会自动忽略它们的值,如果这样的值在数组中会被替换成null(这样数组的索引信息就不会被改变)。如果这样的值出现在对象的属性中,那这个属性会被排除掉。

    JSON.stringify( undefined );                    // undefined
    JSON.stringify( function(){} );                 // undefined
    
    JSON.stringify( [1,undefined,function(){},4] ); // "[1,null,null,4]"
    JSON.stringify( { a:2, b:function(){} } );      // "{"a":2}"
    

    JSON.stringify()格式化一个循环引用的对象,会抛出异常

    JSON字符串有一个特殊的行为,如果一个对象定义了toJSON()方法,那这个方法先被调用,并且将它返回的值进行序列化。

    如果将一个含有非法JSON值的对象序列化成JSON字符串,需要定义一个toJSON()方法,用于返回该对象的JSON安全版本。

    var o = { };
    
    var a = {
        b: 42,
        c: o,
        d: function(){}
    };
    
    // create a circular reference inside `a`
    o.e = a;
    
    // would throw an error on the circular reference
    // JSON.stringify( a );
    
    // define a custom JSON value serialization
    a.toJSON = function() {
        // only include the `b` property for serialization
        return { b: this.b };
    };
    
    JSON.stringify( a ); // "{"b":42}"
    

    常见的误解是toJSON()应该返回一个对象的JSON字符串。这是错误的,toJSON应该返回一个任何类型的正常值,并且JSON.stringify()本身会将这个值进行序列化。

    JSON.stringify()第二个参数是个可选参数,被称为replacer。这个参数可以是数组或者函数。它提供了一个过滤机制制定了应该或者不应该包含哪些属性,从而实现了对象可定制的递归序列化,这种做法和toJSON()如何序列化准备一个值很相似。

    如果replacer是一个数组,它应该是一个字符串数组,每一个值都指定了对象的属性名称,代表属性应该被加入到序列化中,如果一个属性不在这个列表中,它会被跳过。

    如果replacer是一个函数,它首先会被该对象调用一次,然后该对象的每个属性会调用一次,每次都会给这个函数传递两个值,key和value。想在序列化过程中跳过某个key,只需要返回undefined,否则返回提供的value。

    const obj = {
        a: 0,
        b: 1,
        c: [0, 1, 2]
    }
    JSON.stringify(obj,['a', 'c']) // "{"a":0,"c":[0,1,2]}"
    
    JSON.stringify(obj,(key,value)=>{
        if(key !== 'b'){
            return value
        }
    })
    // "{"a":0,"c":[1,2,3]}"
    

    replacer为函数时,第一次调用时,会把obj对象自身传递进去。if语句过滤掉名称为"b"的属性。字 符串是递归进行的,所以数组[1,2,3]中的每个值都被传递给replacer的参数value,对应的下标(0,1,2)作为参数key

    第三个可选的参数也可以传递给JSON.stringify(),被称为space,被用作缩进,是为了使得输出有格式更加漂亮。space可以是一个正整数,指定每层缩进应该缩进多少个空格。或者space也可以是个字符串,其值的前十个字符被用于每个缩进层次。

    const a = {
        b: 42,
        c: "42",
        d: [1,2,3]
    };
    
    JSON.stringify( a, null, 3 );
    // "{
    //    "b": 42,
    //    "c": "42",
    //    "d": [
    //       1,
    //       2,
    //       3
    //    ]
    // }"
    
    JSON.stringify( a, null, "-----" );
    // "{
    // -----"b": 42,
    // -----"c": "42",
    // -----"d": [
    // ----------1,
    // ----------2,
    // ----------3
    // -----]
    // }"
    

    相关文章

      网友评论

          本文标题:JSON.stringify详解

          本文链接:https://www.haomeiwen.com/subject/ynlwxctx.html