当前位置 : 主页 > 网络编程 > JavaScript >

JavaScript语法JSON序列化之stringify实例详解

来源:互联网 收集:自由互联 发布时间:2023-01-17
目录 介绍 语法 案例 value replacer space toJSON 总结 介绍 什么是序列化,序列化就是将对象数据转换为可以存储或者传输的过程。在js中,经常使用JSON来进行数据的序列化和反序列化,需要
目录
  • 介绍
  • 语法
  • 案例
    • value
    • replacer
    • space
    • toJSON
  • 总结

    介绍

    什么是序列化,序列化就是将对象数据转换为可以存储或者传输的过程。在js中,经常使用JSON来进行数据的序列化和反序列化,需要注意的是JavaScript不是JSON,JSON也不是JavaScript。

    虽然JSON是基于JavaScript语法,但是JSON并不是Javascript的子集。JSON序列化是将对象或值转换为JSON字符串,并提供对应的解析JSON字符串的方法。

    语法

    JSON.stringify(value[, replacer [, space]])可将一个js对象或值转换为JSON字符串,其一共有三个参数,如果指定了replacer且为函数,则被序列化的每一个值都会经过此函数的处理;如果replacer为数组,则只有在数组中的属性才会被序列化。

    value:将要被序列化的值,可为js对象或普通值

    replacer:可选参数

    • 如果该参数指定为一个函数,则在序列化的过程中,被序列化的值的每一个属性都将经过函数的转换和处理,最终的JSON字符串将与函数有关
    • 如果该参数指定为一个数组,则在序列化的过程中,只有包含在数组中的属性名才会被序列化,最终的JSON字符串与原数据相比是做了“过滤”
    • 如果该参数未指定、指定为null或指定为其他值,则在序列化的过程中,所有的属性都将被序列化

    space:可选参数

    • 指定用于缩进的空白字符串个数
    • 如果参数的值为数字,则表示有多少个空格;最大值为10,若小于1,则表示没有空格
    • 如果参数的值为字符串,则该字符串被视为空格,用于美化输出;如果字符串长度超过10,则截取前10
    • 如果没有提供,或提供为null,则表示没有空格

    异常情况

    • 尝试转换循环引用时,会抛出异常
    • 尝试转换BigInt类型时,也会抛出异常
    • 如果不确定被转换数据的类型,可将JSON.stringify()放入try/catch中执行

    案例

    value

    将对象或值转换为JSON字符串

    • 如果被转换对象中含有toJSON() 方法,则最终的JSON字符串有toJSON()决定,因此需要注意不能在方法中轻易覆盖此方法。
    • 非数组对象在被序列化后,不保证其属性还是按照特定的顺序出现在JSON字符串
    • 布尔值、数字、字符串的包装类型,即通过new Boolean()new Number()new String()创建的数据,在转换时会自动转换成对应的基本数据类型
    • 函数、undefined单独被转换时,会返回undefined;函数、undefined、symbol在序列化过程中,如果出现在数组中则转换为null,如果为非数组的属性则会被忽略
    • 无法转换存在循环引用的对象
    • NaN、Infinity、null都会被转换为null
    • 所有以symbol为键的属性都会被忽略掉,即使在replacer函数中强制指定了需要包含这些属性
    • 其他类型的对象,则仅会序列化可枚举属性
    // 基础值和对象
    JSON.stringify({}) // '{}'
    JSON.stringify('str') // '"str"'
    JSON.stringify("str") // '"str"'
    JSON.stringify(true) // 'true'
    ​
    JSON.stringify([new Number(2), new String('true'), new Boolean(true)]) // 包装类型,转换为对应的基本类型。'[1, "true", true]'
    JSON.stringify(undefined) // 单独转换,undefined
    JSON.stringify(function () {}) // 单独转换,undefined
    JSON.stringify([undefined, function () {}, Object, Symbol(1)]) // 如果出现在数组中,则转换为null,'[null, null,null, null]'
    JSON.stringify({x:undefined, y:function () {}, Object, z:Symbol(1)}) // 如果出现在非数组对象中,则会被忽略,'{}'
    ​
    // 以Symbol为键的属性都会被忽略
    JSON.stringify({[Symbol('key')]: 'value'}) // '{}', 忽略Symbol
    JSON.stringify({[Symbol('key')]: 'value'}, [Symbol('key')]) // '{}', 就算数组中包含也会忽略
    JSON.stringify({[Symbol('key')]: 'value'}, function (k, v) {
        if (k === 'symbol') {
            return 'symbol'
        }
    }) // undefined, 就算是在replacer中强制指定,也会被忽略
    ​
    JSON.stringify(NaN) // null
    JSON.stringify(null) // null
    JSON.stringify(Infinity) // null
    

    replacer

    replacer可以是一个函数,也可是一个数组。如果是函数,则有两个参数,分别为key和value,两者都可以被序列化;如果是数组,则仅在数组中的属性会被序列化。

    function replacer (key, value) {
        if (typeof value === 'boolean') {
            return undefined;
        } else if (typeof value === 'string') {
            return {
                flag: true
            }
        } else if (typeof value === 'number') {
            return function () {
                console.log('value', value)
            }
        } else if (Array.isArray(value)) {
            return {
                isArr: true
            };
        }
        return value
    }
    let obj = {
        bool: false,
        str: 'hello',
        num: 10,
        arr: [20]
    }
    let jsonStr = JSON.stringify(obj, replacer); // '"str": {}, "arr": {}'
    // 如果返回为undefined,则该属性不会显示在JSON字符串中
    // 如果返回为对象,则该对象递归调用replacer序列化成JSON字符串
    // 如果返回为函数,则该函数不会被序列化成JSON字符串
    // 由于存在递归调用,因此需要避免超出最大调用栈
    ​
    jsonStr = JSON.stringify(obj, ['bool', 'num']) // '{"bool": false, "num": 10}', 如果是数组,则仅会序列化数组中的属性
    

    space

    用来控制序列化后的JSON字符串里面空格的间距。如果是数字,则表示缩进多少个空格;如果是字符串,则用该字符串代替空格。space的最大长度为10

    JSON.stringify({
        x: 10,
        y: 20
    }, null, 4); // '{\n    "x": 10,\n    "y": 20\n}'
    JSON.stringify({
        x: 10,
        y: 20
    }, null, 'hello'); // '{\nhello"x": 10,\nhello"y": 20\n}'
    

    toJSON

    如果一个被序列化的对象拥有toJSON方法,则该方法就会覆盖默认的序列化行为,即不是该对象被序列化,而是调用toJSON方法后返回的值被序列化。

    let obj = {
        x: 10,
        y: 30,
        toJSON: function() {
            return {z: 40};
        }
    };
    JSON.stringify(obj); // '30',序列化的是toJSON返回的值,而不是整个对象
    JSON.stringify({x: obj}, function(k, v) {
        if (v.z == 40) {
            return {z: 50}
        }
        return v;
    }); // '{"x":{"z":50}}',使用replacer函数处理的也是处理的是toJSON返回的值,而不是整个对象
    

    总结

    • JSON可使用stringify方法实现对象或值的序列化
    • replacer参数可以是函数,也可以是数组。函数用来处理被序列化的值的每一个属性,数组表示只序列化哪些属性,两者可以在某些场景下实现相同的效果
    • 被序列化的对象如果有toJSON方法,则序列化的是该方法返回的值
    • JSON.stringify可与localStorage结合使用,用于存储登录信息等;也可用于简单的深拷贝
    • 合理使用第二个参数replacer,可更好的处理序列化对象时可能被忽略、转换的属性值
    • 在序列化时可能会抛出异常,可将其放入try/catch中执行

    以上就是JavaScript语法 JSON序列化之stringify实例详解的详细内容,更多关于JavaScript JSON 序列化 stringify的资料请关注自由互联其它相关文章!

    上一篇:JavaScrip如何安全使用PaymentRequestAPI详解
    下一篇:没有了
    网友评论