JSON

json的應(yīng)用早在2001年就已經(jīng)開始了,JSON是JavaScript的一個嚴格的子集,利用JavaScript中的一些模式來表示結(jié)構(gòu)化數(shù)據(jù)。JSON是一種數(shù)據(jù)格式,不是一種編程語言,雖然具有相同的語法形式,但JSON并不從屬于JavaScript。

一、語法

json的語法可以表示一下三種類型的值

  • 簡單值:可以在JSON中表示字符串、數(shù)值、布爾值和null,但JSON不支持JavaScript中的特殊值undefined
  • 對象
  • 數(shù)組
    例如:json數(shù)據(jù)格式
{
    "name":"anxiaoyan",
    "age":22,
    "school":{
        "name":"NWAFU",
        "location":"shanxi·china"
    },
    "hobby":[
    "reading",
    "game",
    "sports"
    ]
}

二、Json解析和序列化

JSON之所以流行,擁有與JavaScript類似的語法并不是全部的原因。更重要的一個原因是,可以把JSON數(shù)據(jù)結(jié)構(gòu)解析為有用的JavaScript對象。
JSON對象有兩個方法:stringify()和parse(),這兩個方法分別用于將JavaScript對象序列化成json字符串和把json字符串解析為原生的JavaScript值。

2.1JavaScript序列化成json字符串

例如:

var book = {
    title:"Professional javascript",
    authors:[
        "Nicholas C.Zakas"
    ],
    edition:3,
    year:2011
};
var jsonText = JSON.stringify(book);

結(jié)果顯示保存在jsonText中的字符串的格式如下所示:

{"title":"Professional javascript","authors":["Nicholas C.Zakas"],"edition":3,"year":2011}

注意:在序列化JavaScript對象時,所有函數(shù)及原型成員都會被有意忽略,不體現(xiàn)在結(jié)果中,,此外值為undefined的任何屬性也都會被跳過,結(jié)果最終都是值為有效的json數(shù)據(jù)類型的實例屬性。

2.2Json字符串解析為JavaScript對象

將JSON字符串直接傳遞給JSON.parse()就可以得到相應(yīng)的JavaScript值

var bookCopy = JSON.parse(jsonText);

返回結(jié)果與book具有相同的屬性,但是他們是兩個相互獨立的,沒有任何關(guān)系的對象。
如果傳給JSON.parse()的字符串不是有效的json,該方法就會拋出錯誤

2.3序列化選項

JSON.stringify()除了要序列化的JavaScript對象之外,它還可接收另外兩個參數(shù),這兩個參數(shù)用于指定以不同方式序列化JavaScript對象,第一個參數(shù)是個過濾器,可以是一個數(shù)據(jù),也可以是一個函數(shù)。第二個參數(shù)是一個選項,表示是否在JSON字符串中保留縮進,單獨或組合使用這兩個參數(shù),可以更加全面的控制JSON的序列化。

2.3.1過濾結(jié)果

  • 如果過濾參數(shù)是個數(shù)組,那么JSON.stringify()的結(jié)果中只包含數(shù)組中列出的屬性。例如:
var book = {
    title:"Professional javascript",
    authors:[
        "Nicholas C.Zakas"
    ],
    edition:3,
    year:2011
};
var jsonText = JSON.stringify(book,["title","edition"]);

console.log(jsonText);

JSON.stringify()第二個參數(shù)是一個數(shù)組,其中包含“title”和“edition”,這兩個屬性將要序列化的對象中的屬性是對應(yīng)的,因此在返回結(jié)果中,只包含這兩個屬性

{"title":"Professional javascript","edition":3}
  • 如果第二個參數(shù)是一個函數(shù),傳入的函數(shù)接收兩個參數(shù),key和value,根據(jù)屬性鍵名可以知道應(yīng)該如何處理要序列化的對象中的屬性,屬性名只能是字符串,而在值并非鍵值對結(jié)構(gòu)的值時,鍵名可以是空字符串,為了改變序列化對象的結(jié)果,函數(shù)返回的值就是相應(yīng)鍵的值,不過注意,如果函數(shù)返回了undefined,那么相應(yīng)的屬性會被忽略。例如:
var book = {
    title:"Professional javascript",
    authors:[
        "Nicholas C.Zakas"
    ],
    edition:3,
    year:2011
};
var jsonText = JSON.stringify(book,function(key,value){
    switch(key){
        case "authors":
            return value.join(",");
        case "year":
            return 5000;
        case "edition":
            return undefined;
        default:
            return value;
    }
});

console.log(jsonText);

如果鍵為authors,就將數(shù)組連接為一個字符串,如果鍵為“year”,將其值設(shè)為5000,如果鍵為“edition”,通過返回undefined刪除該屬性。
序列化之后的JSON字符串為

{"title":"Professional javascript","authors":"Nicholas C.Zakas","year":5000}

2.4字符串縮進

JSON.stringify()的第三個參數(shù)用于控制結(jié)果中的縮進和空白符.

  • 如果這個參數(shù)是一個數(shù)值,那它表示的是每個級別縮進的空格數(shù),例如:要求每個級別縮進四個空格,代碼如下:
var jsonText = JSON.stringify(book,null,4)

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

{
    "title": "Professional javascript",
    "authors": [
        "Nicholas C.Zakas"
    ],
    "edition": 3,
    "year": 2011
}
  • 如果縮進參數(shù)是一個字符串而非數(shù)值,則這個字符串將在json字符串中被用作縮進字符(不再使用空格),例如:
var jsonText = JSON.stringify(book,null,"- -");

這樣,jsonText中的字符串將變成如下所示:

{
- -"title": "Professional javascript",
- -"authors": [
- -- -"Nicholas C.Zakas"
- -],
- -"edition": 3,
- -"year": 2011
}

注意:縮進字符串最長不能超過10個字符,如果字符串長度超過了10個,結(jié)果中將只出現(xiàn)前10個字符

2.4 toJSON()方法

有時候,JSON.stringify()還是不能滿足對某些對象進行自定義序列化的需求,在這些情況下可以對象定義toJSON()方法,返回其自身的JSON數(shù)據(jù)格式??梢詾槿魏螌ο筇砑觮oJSON()方法,例如:

var book = {
    title:"Professional javascript",
    authors:[
        "Nicholas C.Zakas"
    ],
    edition:3,
    year:2011,
    toJSON:function(){
        return this.title;
    }
};
var jsonText = JSON.stringify(book);

以上book對象定義了toJSON()方法,所以JSON.stringify()返回結(jié)果如下:

"Professional javascript"

注意:當toJSON()方法返回undefined,此時如果包含它的對象嵌入在另外一個對象,會導致它的值變?yōu)閚ull,如果它是頂級對象,結(jié)果就是undefined。
toJSON()可以作為函數(shù)過濾器的補充,因此理解序列化的內(nèi)部順序十分重要。假設(shè)把一個對象傳入JSON.stringify()序列化該對象的順序如下:

(1) 如果存在toJSON()方法而且能通過它取得有效的值,則調(diào)用該方法。否則,返回對象本身。
(2)如果提供了第二個參數(shù),應(yīng)用這個函數(shù)過濾器。傳入函數(shù)過濾器的值是第(1)步返回的值
(3)對第(2)步返回的每個值進行相應(yīng)的序列化
(4)如果提供了第三個參數(shù),執(zhí)行相應(yīng)的格式化。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容