JSON现在广泛用于前后台数据交互,是现在最流行的交互数据格式。通过看书,网络学习后,加以实践验证,取得理解后,将JOSN这块的大部分常用知识点总结了起来,如有不对地方,望指正。

JSON分类

1、简单的JSON对象

{
        "name": "ys",
        "age": 12
    }

可能好学的人会联想到,这不是和对象直接量定义对象一样吗?我们看看对象直接量

//键值名带引号
    var person = {
        "name": "ys",
        "age": 12
    };
    console.log(typeof person); //Object
    //键值名不带引号
    var person = {
        name: "ys",
        age: 12
    };
    console.log(typeof person);//Object

既然这么相像,这也就奠定了JSON在数据交互中的地位,是不是可以互相转换,从而用JavaScript的方法去调用他,答案是肯定的,下文有详解。

二者的区别如下:

  • 对象直接量有声明变量(JSON中没有变量)
  • 对象直接量是JavaScript语句,所以末尾有“;”
  • 对象直接量键值名引号可有可无,而JSON中则必须带引号

2、复杂的JSON对象(JSON数组)

//①
    ["ys", 12]
//②
    [
        {
            "name": "ys",
            "age": 12
        },
        {
            "name": "hh",
            "age": 13
        }
    ]
//③
    [
        {
            "name": "ys",
            "age": 12,
            "like": ["eat", "drink"]
        },
        {
            "name": "hh",
            "age": 13,
            "like": ["language", "write"]
        }
    ]
//④
    [
        {
            "name": "ys",
            "age": 12,
            "like": {
                "eat": "banana",
                "drink": "water"
            }
        },
        {
            "name": "hh",
            "age": 13,
            "like": {
                "language": "Chinese",
                "write": "novel"
            }
        }
    ]

JSON数组数据层层加深,因此可以表示复杂的数据

JSON字符串和JSON对象

我刚开始用JSON的时候,一直搞不明白JOSN字符串和JSON对象的区别,这个听起来很简单,但是实际开发过程中确实状态百出,有时候后台传过来的是JSON字符串,而我们当做JavaScript对象处理,调用方法,那自然就会出错。

1、stringify()方法 —-参数(必选),[可选],[可选]

var myMes= {
        "name": "ys",
        "age": 12
    };

    console.log(typeof myMes);//Object

    var jsonText = JSON.stringify(myMes);
    console.log(typeof jsonText);//String

用法如上,作用是将json对象转化为json字符串。
类型变换:Object -> String

2、parse()方法—-参数(必选),[可选]

var myMes= {
        "name": "ys",
        "age": 12
    }; 
    console.log(typeof myMes);//Object
    //为了模拟json字符串
    var jsonText = JSON.stringify(myMes);
    console.log(typeof jsonText);//String

    var jsonObj = JSON.parse(jsonText);
    console.log(typeof jsonObj);//Object

用法如上,作用是将json字符串转化为json对象,为了模拟json字符串,我们先用stringify方法制造了一个json字符串。
类型变化:String -> Object

JSON序列化

1、json数据过滤
有些时候我们只需要json数据中的某几条作为结果,这个时候我们可以对json数据进行过滤

stringify()可以接受第二个参数,【过滤条件】,返回过滤后的json对象

①数组条件过滤,如[“name”, “age”]

var myMes = {
        "name": "ys",
        "age": 12,
        "like": "drink",
        "nationality": "China"
    };
    /*实现过滤,只留下name和age*/
    var jsonText = JSON.stringify(myMes, ["name", "age"]);
    console.log(jsonText);         //{"name": "ys", "age": 12}

②函数条件过滤
当使用函数条件过滤时候,我们就可以按照我们需求去做出处理了,如:

var myMes= {
        "name": "ys",
        "age": 12,
        "like": "drink",
        "nationality": "China"
    };
    var jsonText = JSON.stringify(myMes, function(key, value){
        switch(key){
            case "name": 
                return "名字改变了";
            default: 
                return value;
        }
    }, 4);
    console.log(jsonText);

运行结果如图:

demjson处理keyvalue不带引号的json数据 json的键值不带引号_parse

对于第三个参数,上述代码中4的用法,下文有讲,关于这个函数过滤function(key, value){},key为键值对名,value存储值,我追踪了一下value值,如下图:

demjson处理keyvalue不带引号的json数据 json的键值不带引号_json_02


为什么循环次数为【键值+1】,因为第一次循环的时候,key=“”

2、json字符串格式序列化
也就是用到stringify()的第三个参数,如例子:

var myMes= {
        "name": "ys",
        "age": 12,
        "like": "drink",
        "nationality": "China"
    };
    var jsonText = JSON.stringify(myMes, ["name", "age"], 4);
    console.log(jsonText);//{"name": "ys", "age": 12}

如上代码,我们给stringify()设置了第三个参数,【缩进控制】,效果图如下:

demjson处理keyvalue不带引号的json数据 json的键值不带引号_parse_03

3、toJSON()方式
实现自定义序列化方法,具有优先执行性。

var myMes = {
        "name": "ys",
        "age": 12,
        toJSON: function(){
            return this.name;
        }
    };
    var jsonText = JSON.stringify(myMes);
    console.log(jsonText);

结果为

demjson处理keyvalue不带引号的json数据 json的键值不带引号_toJSON_04

序列化也说完了,总结一下他的执行机理。

  • ① 如果存在toJSON()方法,且能通过他取得有效的值,则调用该方法,否则返回对象本身。
  • ② 通过第一步得到值之后,如果有过滤函数。则将返回值传入到过滤函数
  • ③ 通过过滤函数序列化后,如果存在第三个参数【格式控制】话,则格式化。

JSON解析

json字符串中包含对象如何正确解析

parse()第二个参数的用法,我们又叫他“还原函数”

//定义一个构造的对象的方法
    function setMessage(eat, drink){
        this.eat = eat;
        this.drink = drink;
        this.getEat = function(){
            return this.eat;
        };
    }
    //定义一个myName的对象 
    var myMes = {
        "name": "ys",
        "age": 12,
        "message": new setMessage("banana", "water")
    };
    //为了模拟json字符串
    var jsonText = JSON.stringify(myMes);

    var jsonObj = JSON.parse(jsonText);
    console.log(jsonObj.message);

结果是

demjson处理keyvalue不带引号的json数据 json的键值不带引号_stringify_05

没错,可以访问到,那么我想访问getEat()方法呢,调用了一下,惊奇的发现是错的,难道我们的代码出现了问题,事实就是这样,因为在由Object -> String -> Object时候,我们的new setMessage()失去了对象的功能。或许你会认为我们只是转化模拟,事实实际开发过程就是这样,数据传输的时候,也是经过了Object -> String -> Object(后台封装对象,传输变成string,解析成Object),问题出现了,那么自然有解决办法。

//定义一个构造的对象的方法
    function setMessage(eat, drink){

        this.eat = eat;
        this.drink = drink;
        this.getEat = function(){
            return "你想吃" + this.eat;
        };
    }
    //定义一个myName的对象 
    var myMes = {
        "name": "ys",
        "age": 12,
        "message": new setMessage("banana", "water")
    };
    //为了模拟json字符串
    var jsonText = JSON.stringify(myMes);

    var jsonObj = JSON.parse(jsonText, function(key, value){
        switch(key){
            case "message":
                return new setMessage(value.eat, value.drink);
            default:
                return value;
        }
    });
    console.log(jsonObj.message.getEat());

结果是

demjson处理keyvalue不带引号的json数据 json的键值不带引号_parse_06

这样我们就顺利解决了,其实,我们可以看到,只要有函数参数,我们就可以用函数去实现很过功能,反而拓展性更强了。

基本上讲完了,如果有不太懂得地方,欢迎交流。