zoukankan      html  css  js  c++  java
  • JSON格式数据

    1. 基础知识

    1. 什么是JSON格式?

    JSON格式是现在网站数据交互的标准数据格式,写入标准。

    • 取代原来的XML;符合JS原生语法,可以被直接解析,不需要额外的解析文件。
    • 书写简单,一目了然

    2. 合格的JSON数据

    1.对象{...}

    1)属性名必须是双引号的字符串;不能是Symbol类型;会被忽略

    2)属性值不能是Date类型、函数、正则表达式、undefined、NaN、Infinity、-Infinity

    JSON.stringify(value)的作用是将值转化为JSON的字符串形式。

    JSON.stringify({a: new Date()});
    // "{"a":"2019-10-12T15:16:13.833Z"}" 
    // new Date()由于toJSON()方法的存在,由对象变成了字符串类型,Date.parse()无法复原JSON
    JSON.stringify({[symbol()]: 5}); // "{}"   Symbol的属性被忽略
    JSON.stringify({a: function(){}}); // "{}" function的属性值被忽略
    JSON.stringify({a: undefined}); // "{}" undefined的属性值被忽略
    JSON.stringify({a: /a/}); // "{"a": {}}" 正则表达式被解析成{}
    JSON.stringify({a: NaN}); // "{"a": null}" NaN被解析成null
    JSON.stringify({a: Infinity}); // "{"a": null}" Infinity被解析成null
    JSON.stringify({a: -Infinity}); // "{"a": null}" -Infinity被解析成null

    3)属性值如果含有字符串,必须全部是双引号

    var obj={ //这是个对象,不是JSON
        a: ['k','m'],
        b: 'n',
        c: {d: 'e'}  
    }
    JSON.stringify(obj);
    /* 标准的JSON格式如下:
        "{
           "a": ["k", "m"],
           "b": "n",
           "c": {"d": "e"}
        }" 
    */

    4)对象不能循环引用,否则无法解析

    let obj ={a: 1}
    let obj2 = {b: 2};
    obj.c = obj2;
    obj2.d = obj;
    
    JSON.stringify(obj2); //Uncaught TypeError: Converting circular structure to JSON

    5) 合格的JSON格式数据最后一个元素后面不能有,

    JSON.stringify({a:1,}); // "{"a":1}" 转为JSON格式,逗号消失,说明JSON不能有逗号

    2. 数组[]

    数组的元素不能是Date,Symbol,RegExp,function,NaN,undefined,Infinity,-Infinity。

    除了正则表达式会被解析成{ },  其余6个都会被解析成null

    最后一个元素后面不能有逗号(,)

    JSON.stringify([Symbol(), undefined, NaN, Infinity,-Infinity,function(){}, /a/]);
    // "[null,null,null,null,null,null,{}]"

    3. 原始数据类型

    字符串、数字(十进制)、布尔值、null

    JSON.stringify('true');//  ""true"" 将字符串单引号变为双引号,再字符串化
    JSON.stringify('true') === ""true"" ;// true
    
    JSON.stringify(0x99); // "153" 不能是十进制以外的数字,会被自动转为十进制,通过JSON.parse()无法还原
    
    JSON.stringify(99); //"99"
    JSON.stringify(true); // "true"
    JSON.stringify(null); //"null" 

    ❎不能是:Symbol、undefined、NaN、Infinity、-Infinity

    前两个会被忽略,和空函数一样,默认返回undefined

    后面的会被解析成null

    JSON.stringify(Symbol()); // undefined
    JSON.stringify(undefined);// undefined
    JSON.stringify(NaN); // "null"
    JSON.stringify(Infinity); // "null"
    JSON.stringify(-Infinity); // "null"

    2. JSON.stringify(value[, replacer, space])

    该方法将任意类型的值,转为JSON对象的字符串格式。

    1)如果对象有自定义的toJSON方法,value将是toJSON的返回值

    Date对象原生含有toJSON()方法。将对象转为字符串,所以Date对象不能作为JSON格式的值。

    // 自定义toJSON()方法
    var obj={
        a: 1,
        toJSON(){
            return {c:1}
        }
    };
    JSON.stringify(obj); //"{"c":1}"

    2)当value是对象时,会过滤掉不可遍历属性

    var obj = {};
    Object.defineProperties(obj, {
        "foo": {
            value: 5,
            enumerable: false
        },
        "bar": {
             value: 6,
             enumerable: true
        }
    });
    obj; // {foo: 5, bar; 6}
    JSON.stringify(obj); // "{"bar": 6}"

    3) 第二个参数可以是数组,只有当value是对象时,表示可以遍历的属性;

    起过滤作用! 可以过滤掉循环引用的属性。

    var obj = {
        foo: {bar: 5},
        bar: {foo: 6},
        tar: 7
    };
    JSON.stringify(obj, ['foo']); // "{"foo": {}}" 因为第二个参数规定了只序列化foo属性,嵌套的属性也适用该规则

    第二个参数还可以是函数function(key,value){},用于处理数据;而且可以递归处理所有的属性。

    该函数默认形式是:

    funtion(key,value){
       return value;
    }

    不论第一个参数是什么类型的值,函数第一次处理的key都没有对应,value是本身;

    如果返回的value值不是原始数据类型,则递归调用函数,函数对应的处理对象都是上次返回的结果。

    a. 当value是对象时,key,value对应对象的键值对

    JSON.stringify({a:1,b:2}, function(key,value) {
        console.log("key=",key, "value=",value);
        return value
    }) // "{"a":1,"b":2}"
    // key=  value= {a: 1, b: 2}
    // key= a value= 1
    // key= b value= 2
    
    JSON.stringify({a:1,b:2}, function(key,value) {
        if(typeof value === 'number') {
            value += 10;
        }
        return value;
    }); // "{"a": 11, "b":12}"

    b. 当value是数组时,key对应数组下标, value对应值

    JSON.stringify([1,2], function(key,value){
        console.log("key=",key, "value=",value);
        return value;
    }) //"[1,2]"
    // key=    value= [1, 2]
    // key= 0 value= 1
    // key= 1 value= 2

    c. 当value是原始类型的值时, 不需要递归调用

    JSON.stringify(5, function(key,value){ return value+5}) //"10"
    JSON.stringify('5', function(key,value){ return value+5}) // "55"

    4)第三个参数主要用来增加可读性,调整返回格式;

     如果参数是一个数字(<10),表示在返回的属性面前的空格数量;

    JSON.stringify({a: {b:1}}, function(key,value) {
        return value
    }, 4);
    /*
    "{
        "a": {
            "b": 1
        }
    }
    */

    如果参数是一个字符串(length<10), 表示在属性前面添加该字符串

    JSON.stringify({a: {b:1}}, function(key,value) {
        return value
    }, '|--');
    /*
    "{
    |--"a": {
    |--|--"b": 1
    |--}
    }"
    */

    3.JSON.parse(value[, function(key,value){}])

    JSON.parse(value)将JSON对象的字符串形式,转为JSON对象;

    value必须是合格JSON数据的字符串,否则会抛出异常!

    所以JSON.parse方法在不能确认参数是否正常的情况下,应该try...catch...

    try{
        JSON.parse("'test'"); 
         // 最外层的引号是字符串格式,里面是JSON数据'test',单引号抛出异常
    } catch {
       console.log("参数格式错误");
    }
    // 其实如果是('"test"')不会抛出异常,字符串包含的是JSON数据"test"

    第二个参数的用法同JSON.stringify()的第二个参数是函数的用法。

  • 相关阅读:
    github代码上传下载慢问题
    React Native环境搭建
    分布式模式之Broker模式
    如何构建技术体系
    https nginx配置
    自我管理--拖延 vs 心理
    idea+maven本地仓库更新问题
    后台服务集群日志管理
    技术男励志圣经
    线段树合并
  • 原文地址:https://www.cnblogs.com/lyraLee/p/11664453.html
Copyright © 2011-2022 走看看