javaScript系列 [05]-javaScript和JSON

本文輸出和JSON有關(guān)的以下內(nèi)容
? JSON和javaScript
? JSON的語法介紹
? JSON的數(shù)據(jù)類型
? JSON和XMLHTTPRequest
? JSON的序列化和反序列化處理

1.1 JSON和javaScript

JSON是一種數(shù)據(jù)交換格式。

JSON的全稱是JavaScript Object Notation,翻譯為JavaScript對象表示法。JSON的這個全稱,無疑讓很多人既興奮又困惑,興奮的人直接認(rèn)為這就是JavaScript中的對象,困惑的人覺察出JSON數(shù)據(jù)和JavaScript對象好像有些不一樣。接下來我們先談一談JSON數(shù)據(jù)和JavaScript的關(guān)系。

誠然,從JSON的全稱可以看出JSON和JavaScript語言必定有種某種神秘關(guān)聯(lián),至少能夠確定的是JSON的命名確實來源于JavaScript這門語言。

JSON基于JavaScript對象字面量,但JSON本身是一種數(shù)據(jù)交換格式,因此它是獨立于語言的。JSON全稱為JavaScript對象表示法,在理解的時候可以認(rèn)為JSON ==> JavaScript && 對象 && 表示法

JavaScript我們知道是一門動態(tài)腳本語言,那么對象表示法是什么?

對象是面向?qū)ο缶幊陶Z言中一種常見的數(shù)據(jù)類型,表示鍵值對的集合,那么表示法是什么?

表示法:是指一個可以表示諸如數(shù)字或單詞等數(shù)據(jù)的字符系統(tǒng)。

JSON起源于JavaScript(靈感來源于JavaScript的對象語法),但真正重要的是具體的表示法本身。JSON不僅獨立于語言,而且使用了一種在許多編程語言中能夠找到共同元素的表達方式?;谶@種簡潔的表達方式,JSON迅速成為一種流行的數(shù)據(jù)交換格式。目前,客戶端和服務(wù)器端在進行數(shù)據(jù)通信的時候,常見的數(shù)據(jù)格式就是JSON和XML。

1.2 JSON的語法介紹

1.2.1 JSON的語法

JSON因為基于JavaScript的字面量,所以我們先來看下JavaScript字面量的樣子,下面給出簡單的代碼示例,描述了一個書對象。

    var  book = {
       name:"聲名狼藉者的生活",
       price:42.00,
       author:"福柯",
       press:"北京大學(xué)出版社",
       read:function () {
           console.log("我的書名為:聲名狼藉者的的生活,作者為???...");
       }
   };

順便貼出一個簡短的JSON數(shù)據(jù)

    {
       "name":"聲名狼藉者的生活",
       "price":42.00,
       "author":"福柯",
       "press":"北京大學(xué)出版社",
       "content":["a","b","c",123]
   }

我們可以對比下上面的JavaScript對象和JSON數(shù)據(jù),會發(fā)現(xiàn)它們的結(jié)構(gòu)和語法形式很像,都是鍵值對的集合,接下來我們做更詳細(xì)的說明。JSON數(shù)據(jù)在表達上和對象保持一致,但因為數(shù)據(jù)交換格式的核心是數(shù)據(jù),所以JSON并不會保存函數(shù)等信息。JSON數(shù)據(jù)所基于的JavaScript對象字面量單純指對象字面量以及其屬性的語法表示。

JSON的主要語法特點

① 以鍵值對的方式來保存數(shù)據(jù)
② 標(biāo)準(zhǔn)的JSON數(shù)據(jù)的key必須要使用雙引號包裹
③ { } 用于表示和存放對象,[ ] 用于表示和存放數(shù)組數(shù)據(jù)

JSON數(shù)據(jù)的讀取,在讀取JSON的時候

{ 表示開始讀取對象,} 表示對象讀取結(jié)束
[ 表示開始讀取數(shù)組,] 表示數(shù)組讀取結(jié)束
:用于分隔鍵值對中的key和value
, 用于分隔對象中的多個鍵值對或者是數(shù)組中的多個元素

JavaScript對象字面量中的key可以使用單引號,可以使用雙引號,可以不必加上引號包裹,但是在JSON中,所有的key必須要加上雙引號。

1.2.2 JSON的驗證和格式化工具

下面列出一些能夠?qū)SON數(shù)據(jù)進行校驗和格式化的在線地址

https://jsonlint.com/
http://tool.oschina.net/codeformat/json
https://jsonformatter.curiousconcept.com/

1.2.3 JSON文件和MIME類型

在開發(fā)中我們經(jīng)常需要處理大量的JSON數(shù)據(jù),JSON這種數(shù)據(jù)交換格式可以作為獨立的文件存在于文件系統(tǒng)中,文件擴展名為 .json

JSON的MIME類型是application/json, 詳細(xì)信息請參考IANA官網(wǎng)維護的所有媒體類型列表。

1.3 JSON的數(shù)據(jù)類型

JSON中(作為value值)的數(shù)據(jù)類型包括對象、字符串、數(shù)字、布爾值、null和數(shù)組六種

① 字符串
JSON中的字符串可以由任何的Unicode字符構(gòu)成,字符串的兩邊必須被雙引號包裹。需要注意的是:雖然在JavaScript語言中字符串可以使用單引號來包裹,但是在JSON中的字符串必須使用雙引號包裹。

如果字符串中存在以下特殊字符,那么需要在它們的前面加上一個反斜線(\)來進行轉(zhuǎn)義。

- "  雙引號
- \  反斜線
- \/ 正斜線
- \b 退格符
- \f 換頁符
- \t 制表符
- \n 換行符
- \r 回車符
- \u 后面跟16進制字符

② 數(shù)字
JSON中的數(shù)字可以是整數(shù)、小數(shù)、負(fù)數(shù)或者是指數(shù)。

③ 布爾類型
JSON數(shù)據(jù)僅僅支持小寫形式的布爾類型值:true 和 false。

④ null類型
JSON中沒有undefined這種數(shù)據(jù)類型,它使用null表示空,并且必須小寫。
在JavaScript語言中,var obj = null 表示把obj這個對象清空,它和undefined不太一樣,null表示什么都沒有,undefined表示未定義。

⑤ 對象類型
對象類型是使用逗號分隔的鍵值對的集合,使用大括號({})裹。

⑥ 數(shù)組類型
數(shù)組類型是元素的集合,每個元素都可以是字符串、數(shù)字、布爾值、對象或者數(shù)組中的任何一種。元素與元素之間使用逗號隔開,所有的元素被方括號([])包裹,建議數(shù)組中所有的元素都應(yīng)該是相同數(shù)據(jù)類型的。

1.4 JSON和XMLHTTPRequest

在前端開發(fā)中有一種發(fā)送網(wǎng)絡(luò)請求的技術(shù)Ajax,它可以實現(xiàn)異步處理網(wǎng)絡(luò)通信而不刷新頁面。

Ajax的全稱為Asynchronous JavaScript and XML,即異步的JavaScript和XML。我們知道JSON的定位是輕量級的數(shù)據(jù)交互格式,客戶端在和服務(wù)器端進行網(wǎng)絡(luò)通信的時候,服務(wù)器端返回給我們的數(shù)據(jù)大多數(shù)是JSON或者是XML。也就是說JSON數(shù)據(jù)在Ajax網(wǎng)絡(luò)通信中可能扮演重要的角色,那什么Ajax不叫異步的JSON而叫做異步的XML呢? 答案是:因為剛提出這種網(wǎng)絡(luò)請求技術(shù)的時候,XML相比JSON更流行。

在Ajax網(wǎng)絡(luò)請求中用到的核心對象XMLHTTPRequest也是如此,其實這個對象命名中包含XML也僅僅是因為對于當(dāng)時而言,XML是網(wǎng)絡(luò)請求中最常用的數(shù)據(jù)交換格式。如果放在今天,那么它們的名字應(yīng)該叫做AjaJ(Asynchronous JavaScript and JSON)和JSONHTTPRequest更合適一些。

1.5 JavaScript中JSON數(shù)據(jù)的序列化和反序列化處理

在網(wǎng)絡(luò)請求中,如果服務(wù)器返回給我們的數(shù)據(jù)是JSON數(shù)據(jù),那么為了方便對數(shù)據(jù)的操作,通常我們在網(wǎng)絡(luò)請求成功拿到JSON數(shù)據(jù)之后會先對JSON數(shù)據(jù)進行反序列化操作。
在前端開發(fā)中,早期的JSON解析基本上由eval函數(shù)來完成,ECMAScript5對解析JSON的行為進行了規(guī)范,定義了全局對象JSON。目前IE8+、FireFox 3.5+、Opera 10.5、Safari 4+和Chrome等瀏覽器均支持原生的JSON全局對象。

JSON數(shù)據(jù)的處理主要涉及到兩方面:序列化處理和反序列化處理

1.5.1 使用eavl函數(shù)來處理JSON數(shù)據(jù)

eavl函數(shù)說明

JavaScript語言中eavl函數(shù)可以把字符串轉(zhuǎn)換為js的代碼并且馬上執(zhí)行,使用情況和Function構(gòu)造函數(shù)用法類型。

    eval("var a = 123;");
    console.log(a + 1);  //輸出結(jié)果為124

因為從某種程度上來講,json其實是JavaScript語言的嚴(yán)格子集,所以我們可以直接通過eval函數(shù)來對json數(shù)據(jù)進行解析。需要注意的是,使用eavl函數(shù)來對json數(shù)據(jù)結(jié)構(gòu)求值存在風(fēng)險,因為可能會執(zhí)行一些惡意代碼。

eavl函數(shù)解析JSON

服務(wù)器返回給前端的json數(shù)據(jù)可能是{...}形式的,也可能是[...]形式的,分別對應(yīng)js中的對象和數(shù)組。如果是{...}形式的,那么在解析的時候,如果直接以eval(json)的方式處理會報錯,因為js中不允許直接寫{name:"zs"}類似的語句。遇到這種結(jié)構(gòu)的json數(shù)據(jù),通常我們有兩種方式進行處理:① 包裝成表達式 ② 賦值給變量。


    //001 [...] 格式的json數(shù)據(jù)
    var arrJson= '[{"name":"zs","age":18},{"name":"lisi","age":28}]';
    var jsonArr = eval(arrJson);

    //002 {...} 格式的json數(shù)據(jù)
    var objJson = `{"name":"wendingding","age":18,"contentAbout":["JavaScript","CSS","HTML"],"car":{"number":"粵A6666","color":"red"}}`;

    //eval(json);  錯誤的演示:報錯
    //處理方式(1):以拼接的方式賦值給變量
    eval("var jsonObj1 = " + objJson);
    //處理方式(2):包裝成表達式
    var jsonObj2 = eval("(" + objJson +")");

    //打印轉(zhuǎn)換后得到的數(shù)組|對象
    console.log(jsonArr);
    console.log(jsonObj1);
    console.log(jsonObj2);

1.5.2 使用JSON全局對象來處理JSON數(shù)據(jù)

JSON全局對象擁有兩個方法:stringify()和parse(),其中parse方法用于把json數(shù)據(jù)反序列化為原生的js,stringify方法用于把js對象序列化為json字符串。

parse方法的使用
語法:JSON.parse(jsonString,[fn])

參數(shù)說明

第一個參數(shù):jsonString為要解析的json字符串
第二個參數(shù):fn是一個可選參數(shù),該參數(shù)為函數(shù)類型,接收兩個參數(shù),分別是每個鍵值對的key和value。


    //json字符串
    var objJson = `{"name":"wendingding","age":18,"contentAbout":["JavaScript","CSS","HTML"],"car":{"number":"粵A6666","color":"red"}}`;

    //把json字符串轉(zhuǎn)換為js數(shù)組
    var arrJson= '[{"name":"zs","age":18},{"name":"lisi","age":28}]';

    //把json字符串轉(zhuǎn)換為js對象
    var jsonObj = JSON.parse(objJson);
    var jsonArr = JSON.parse(arrJson);
    console.log(jsonObj);
    console.log(jsonArr);

    //演示parse方法中函數(shù)參數(shù)的使用
    function fn(key, value) {
        if (key === "name") {
            return value + "++"         //在原有value值的基礎(chǔ)上拼接++字符串
        } else if (key === "age") {
            return undefined            //如果返回undefined,則表示刪除對應(yīng)的鍵值對
        } else {
            return value                //正常返回對應(yīng)的value值
        }
    }
    console.log(JSON.parse(objJson, fn));

stringify方法使用說明

語法:JSON.stringify(Obj,[fn|arr],[space])

參數(shù)說明

第一個參數(shù):Obj為要進行序列化操作的JavaScript對象
第二個參數(shù):過濾器,可以是函數(shù)或者是一個數(shù)組
第三個參數(shù):是否在生成的json字符串中保留縮進,用于控制縮進的字符

    //js中的普通對象
    var obj = {
        name:"zs",
        age:18,
        friends:["小霸王","花仙子","奧特曼"],
        other:undefined,
        showName:function () {
            console.log(this.name);
        }

    };

    //把js中的對象轉(zhuǎn)換為json字符串
    //注意:
    //001 如果鍵值對中存在value值為undefined的數(shù)據(jù),那么會被跳過
    //002 對象中的方法以及該對象的原型成員數(shù)據(jù)在進行轉(zhuǎn)換的時候,會被有意忽略
    console.log(JSON.stringify(obj));

    //控制縮進,該參數(shù)的值可以是數(shù)字也可以是字符串,自動換行
    //001 如果是字符串那么會把對應(yīng)的字符拼接在鍵值對前面,超過10個字符的省略
    //002 如果是數(shù)字那么會設(shè)置對應(yīng)的縮進,最多為10,超過則默認(rèn)為10
    console.log(JSON.stringify(obj, null, 4));
    console.log(JSON.stringify(obj, null, "@@"));

    //過濾器(數(shù)組):表示只處理key為name和age這兩個鍵值對
    console.log(JSON.stringify(obj, ["name","age"]));

    //過濾器(函數(shù)):
    function fn(key,value) {
        if (key === "age")
        {
            return value + 20;
        }else if (key === "name")
        {
            return undefined;       //過濾掉key為name這個鍵值對
        }else
        {
            return value;
        }
    }
    console.log(JSON.stringify(obj,fn));

JSON數(shù)據(jù)總結(jié)

? JSON全稱是JavaScript Object Notation基于JavaScript,是JavaScript的子集。
? JSON雖然是JavaScript的子集,但并不從屬于JavaScript,它獨立于語言。
? JSON是用來表示和傳輸數(shù)據(jù)的格式,比XML更輕量級,現(xiàn)已成為web數(shù)據(jù)交換的事實標(biāo)準(zhǔn)。
? JSON的優(yōu)勢在于其可以方便的把JSON字符串?dāng)?shù)據(jù)轉(zhuǎn)換為對應(yīng)的對象,比XML更方便且數(shù)據(jù)更小。
? JSON語法可以表示:字符串、數(shù)值、布爾值、null、對象和數(shù)組6種類型的值,不支持undefined。
? JSON中的"鍵"區(qū)別于JavaScript,必須要加上雙引號。
? JSON解析可以使用傳統(tǒng)的eval函數(shù),或ECMAScript5推出的全局對象來處理。

參考資料

JSON官網(wǎng):http://json.org/
JSON維基百科:https://en.wikipedia.org/wiki/JSON
JSON作者簡介:https://en.wikipedia.org/wiki/Douglas_Crockford
JSON必知必會:https://book.douban.com/subject/26789960/
JavaScript高級程序設(shè)計:https://book.douban.com/subject/10546125/


最后編輯于
?著作權(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)容

  • 第2章 基本語法 2.1 概述 基本句法和變量 語句 JavaScript程序的執(zhí)行單位為行(line),也就是一...
    悟名先生閱讀 4,613評論 0 13
  • 第3章 基本概念 3.1 語法 3.2 關(guān)鍵字和保留字 3.3 變量 3.4 數(shù)據(jù)類型 5種簡單數(shù)據(jù)類型:Unde...
    RickCole閱讀 5,540評論 0 21
  • 小時候自己幾乎沒有任何照片,能找得出來最早的照片應(yīng)該是一次和媽媽及兄妹在游樂園拍的唯一一張,那時候大概十歲。所以小...
    漁歌子珊閱讀 1,083評論 0 0
  • 是否有人愿意在每年的跨年之時為我編寫一首除夕之歌?雖然我知道這近乎于幻想,可我相信沒有無端的幸福,幸福源于夢想的實...
    清夜獨思閱讀 479評論 0 1
  • #import"ViewController.h" @interfaceViewController() @pro...
    孟維學(xué)閱讀 663評論 0 0

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