整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          程序員都應該了解的一種數據格式之 JSON

          者 | 豬哥

          責編 | maozz

          JSON的誕生原因是因為XML整合到HTML中各個瀏覽器實現的細節(jié)不盡相同,所以道格拉斯·克羅克福特(Douglas Crockford) 和 奇普·莫寧斯達(Chip Morningstar)一起從JS的數據類型中提取了一個子集,作為新的數據交換格式,因為主流的瀏覽器使用了通用的JavaScript引擎組件,所以在解析這種新數據格式時就不存在兼容性問題,于是他們將這種數據格式命名為 “JavaScript Object Notation”,縮寫為 JSON,由此JSON便誕生了!

          今天我們來學習一下JSON的結構形式、數據類型、使用場景以及注意事項吧!

          JSON格式

          上面我們知道JSON是從JavaScript的數據類型中提取出來的子集,那JSON有幾種結構形式呢?又有哪些數據類型呢?他們又分別對應著JavaScript中的哪些數據類型呢?

          JSON的2種結構形式,鍵值對形式和數組形式。

          舉了一個JSON的實例,就是鍵值對形式的,如下:

          {

          "person": {

          "name": "pig",

          "age": "18",

          "sex": "man",

          "hometown": {

          "province": "江西省",

          "city": "撫州市",

          "county": "崇仁縣"

          }

          }

          }

          這種結構的JSON數據規(guī)則是:一個無序的“‘名稱/值’對”集合。一個對象以 {左括號 開始, }右括號 結束。每個“名稱”后跟一個 :冒號 ;“‘名稱/值’ 對”之間使用 ,逗號 分隔。

          因為大多數的時候大家用的JSON可能都是上面那種key-value形式,所以很多人在講解JSON的時候總是會忽略數組形式,這一點是需要注意的。

          那JSON的數組形式是怎么樣的呢?舉一個實例吧!

          ["pig", 18, "man", "江西省撫州市崇仁縣"]

          數組形式的JSON數據就是值(value)的有序集合。一個數組以 [左中括號 開始, ]右中括號 結束。值之間使用 ,逗號 分隔。

          JOSN的6種數據類型

          上面兩種JSON形式內部都是包含value的,那JSON的value到底有哪些類型,而且上期我們說JSON其實就是從Js數據格式中提取了一個子集,那具體有哪幾種數據類型呢?

          1. string:字符串,必須要用雙引號引起來。

          2. number:數值,與JavaScript的number一致,整數(不使用小數點或指數計數法)最多為 15 位,小數的最大位數是 17。

          3. object:JavaScript的對象形式,{ key:value }表示方式,可嵌套。

          4. array:數組,JavaScript的Array表示方式[ value ],可嵌套。

          5. true/false:布爾類型,JavaScript的boolean類型。

          6. :空值,JavaScript的。

          以上數據形式圖片來源JSON官方文檔:http://www.json.org/json-zh.html

          JSON使用場景

          介紹完JSON的數據格式,那我們來看看JSON在企業(yè)中使用的比較多的場景。

          接口返回數據和序列化。JSON用的最多的地方莫過于Web了,現在的數據接口基本上都是返回的JSON,具體細化的場景有:

          1. Ajxa異步訪問數據

          2. RPC遠程調用

          3. 前后端分離后端返回的數據

          4. 開放API,如百度、高德等一些開放接口

          5. 企業(yè)間合作接口

          這種API接口一般都會提供一個接口文檔,說明接口的入參、出參等,

          一般的接口返回數據都會封裝成JSON格式,比如類似下面這種

          {

          "code": 1,

          "msg": "success",

          "data": {

          "name": "pig",

          "age": "18",

          "sex": "man",

          "hometown": {

          "province": "江西省",

          "city": "撫州市",

          "county": "崇仁縣"

          }

          }

          }

          程序在運行時所有的變量都是保存在內存當中的,如果出現程序重啟或者機器宕機的情況,那這些數據就丟失了。一般情況運行時變量并不是那么重要丟了就丟了,但有些內存中的數據是需要保存起來供下次程序或者其他程序使用。

          保存內存中的數據要么保存在數據庫,要么保存直接到文件中,而將內存中的數據變成可保存或可傳輸的數據的過程叫做序列化,在Python中叫pickling,在其他語言中也被稱之為serialization,marshalling,flattening等等,都是一個意思。

          正常的序列化是將編程語言中的對象直接轉成可保存或可傳輸的,這樣會保存對象的類型信息,而JSON序列化則不會保留對象類型!

          為了讓大家更直觀的感受區(qū)別,豬哥用代碼做一個測試,大家一目了然

          1. Python對象直接序列化會保存class信息,下次使用loads加載到內存時直接變成Python對象。

          2. JSON對象序列化只保存屬性數據,不保留class信息,下次使用loads加載到內存可以直接轉成dict對象,當然也可以轉為Person對象,但是需要寫輔助方法。

          對于JSON序列化不能保存class信息的特點,那JSON序列化還有什么用?答案是當然有用,對于不同編程語言序列化讀取有用,比如:我用Python爬取數據然后轉成對象,現在我需要將它序列化磁盤,然后使用Java語言讀取這份數據,這個時候由于跨語言數據類型不同,所以就需要用到JSON序列化。

          存在即合理,兩種序列化可根據需求自行選擇!

          最后就是生成Token和配置文件

          首先聲明Token的形式多種多樣,有JSON、字符串、數字等等,只要能滿足需求即可,沒有規(guī)定用哪種形式。

          JSON格式的Token最有代表性的莫過于JWT(JSON Web Tokens)。

          隨著技術的發(fā)展,分布式web應用的普及,通過Session管理用戶登錄狀態(tài)成本越來越高,因此慢慢發(fā)展成為Token的方式做登錄身份校驗,然后通過Token去取Redis中的緩存的用戶信息,隨著之后JWT的出現,校驗方式更加簡單便捷化,無需通過Redis緩存,而是直接根據Token取出保存的用戶信息,以及對Token可用性校驗,單點登錄更為簡單。

          使用JWT做過app的登錄系統(tǒng),大概的流程就是:

          1. 用戶輸入用戶名密碼

          2. app請求登錄中心驗證用戶名密碼

          3. 如果驗證通過則生成一個Token,其中Token中包含:

          4. 用戶的uid、Token過期時間、過期延期時間等,然后返回給app

          5. app獲得Token,保存在cookie中,下次請求其他服務則帶上

          6. 其他服務獲取到Token之后調用登錄中心接口驗證

          7. 驗證通過則響應

          JWT登錄認證有哪些優(yōu)勢:

          1. 性能好:服務器不需要保存大量的session

          2. 單點登錄(登錄一個應用,同一個企業(yè)的其他應用都可以訪問):使用JWT做一個登錄中心基本搞定,很容易實現。

          3. 兼容性好:支持移動設備,支持跨程序調用,Cookie 是不允許垮域訪問的,而 Token 則不存在這個問題。

          4. 安全性好:因為有簽名,所以JWT可以防止被篡改。更多JWT相關知識自行在網上學習,本文不過多介紹!

          說實話JSON作為配置文件使用場景并不多,最具代表性的就是npm的package.json包管理配置文件了,下面就是一個npm的package.json配置文件內容。

          {

          "name": "server", //項目名稱

          "version": "0.0.0",

          "private": true,

          "main": "server.js", //項目入口地址,即執(zhí)行npm后會執(zhí)行的項目

          "scripts": {

          "start": "node ./bin/www" ///scripts指定了運行腳本命令的npm命令行縮寫

          },

          "dependencies": {

          "cookie-parser": "~1.4.3", //指定項目開發(fā)所需的模塊

          "debug": "~2.6.9",

          "express": "~4.16.0",

          "http-errors": "~1.6.2",

          "jade": "~1.11.0",

          "morgan": "~1.9.0"

          }

          }

          但其實JSON并不合適做配置文件,因為它不能寫注釋、作為配置文件的可讀性差等原因。

          配置文件的格式有很多種如:toml、yaml、xml、ini等,目前很多地方開始使用yaml作為配置文件格式。

          JSON在Python中的使用

          最后我們來看看Python中操作JSON的常用方法有哪些,在Python中操作JSON時需要引入json標準庫。

          import json

          類型轉換

          Python類型轉JSON:json.dump

          # 1、Python的dict類型轉JSON

          person_dict = {'name': 'pig', 'age': 18, 'sex': 'man', 'hometown': '江西撫州'}

          # indent參數為縮進空格數

          person_dict_json = json.dumps(person_dict, indent=4)

          print(person_dict_json, '\n')

          # 2、Python的列表類型轉JSON

          person_list = ['pig', 18, 'man', '江西撫州']

          person_list_json = json.dumps(person_list)

          print(person_list_json, '\n')

          # 3、Python的對象類型轉JSON

          person_obj = Person('pig', 18, 'man', '江西撫州')

          # 中間的匿名函數是獲得對象所有屬性的字典形式

          person_obj_json = json.dumps(person_obj, default=lambda obj: obj.__dict__, indent=4)

          print(person_obj_json, '\n')

          執(zhí)行結果:

          JSON轉Python類型:json.loads

          # 4、JSON轉Python的dict類型

          person_json = '{ "name": "pig","age": 18, "sex": "man", "hometown": "江西撫州"}'

          person_json_dict = json.loads(person_json)

          print(type(person_json_dict), '\n')

          # 5、JSON轉Python的列表類型

          person_json2 = '["pig", 18, "man", "江西撫州"]'

          person_json_list = json.loads(person_json2)

          print(type(person_json_list), '\n')

          # 6、JSON轉Python的自定義對象類型

          person_json = '{ "name": "pig","age": 18, "sex": "man", "hometown": "江西撫州"}'

          # object_hook參數是將dict對象轉成自定義對象

          person_json_obj = json.loads(person_json, object_hook=lambda d: Person(d['name'], d['age'], d['sex'], d['hometown']))

          print(type(person_json_obj), '\n')

          執(zhí)行結果如下:

          對應的數據類型

          上面我們演示了Python類型與JSON的相互轉換,最開始的時候我們講過JSON有6種數據類型,那這6種數據類型分別對應Python中的哪些數據類型呢?

          需要注意的點

          JSON的鍵名和字符串都必須使用雙引號引起來,而Python中單引號也可以表示為字符串,所以這是個比較容易犯的錯誤!

          Python類型與JSON相互轉換的時候到底是用load/dump還是用loads\dumps?

          • 他們之間有什么區(qū)別?

          • 什么時候該加s什么時候不該加s?

          這個我們可以通過查看源碼找到答案:

          不加s的方法入參多了一個fp表示filepath,最后多了一個寫入文件的操作。

          所以我們在記憶的時候可以這樣記憶:

          加s表示轉成字符串(str),不加s表示轉成文件。

          Python自定義對象與JSON相互轉換的時候需要輔助方法來指明屬性與鍵名的對應關系,如果不指定一個方法則會拋出異常!

          相信有些看的仔細的同學會好奇上面使用json.dumps方法將Python類型轉JSON的時候,如果出現中文,則會出現:

          \u6c5f\u897f\u629a\u5dde

          這種東西,這是為什么呢?

          原因是:Python 3中的json在做dumps操作時,會將中文轉換成unicode編碼,并以16進制方式存儲,而并不是UTF-8格式!

          總結

          今天我們學習了JSON的2種形式,切記JSON還有[...]這種形式的。

          學習了JSON的6種數據類型他們分別對于Python中的哪些類型。

          了解了JSON的一些使用場景以及實際的例子。

          還學習了在Python中如何使用JSON以及需要注意的事項。

          一個JSON知識點卻分兩篇長文(近萬字)來講,其重要性不言而喻。因為不管你是做爬蟲、還是做數據分析、web、甚至前端、測試、運維,JSON都是你必須要掌握的一個知識點

          本文為作者投稿,版權歸作者個人所有。

          設我們有一個復雜的對象,我們希望將其轉換為字符串,以通過網絡發(fā)送,或者只是為了在日志中輸出它。

          當然,這樣的字符串應該包含所有重要的屬性。

          我們可以像這樣實現轉換:

          let user = {
            name: "John",
            age: 30,
          
            toString() {
              return `{name: "${this.name}", age: ${this.age}}`;
            }
          };
          
          alert(user); // {name: "John", age: 30}

          ……但在開發(fā)過程中,會新增一些屬性,舊的屬性會被重命名和刪除。每次更新這種 toString 都會非常痛苦。我們可以嘗試遍歷其中的屬性,但是如果對象很復雜,并且在屬性中嵌套了對象呢?我們也需要對它們進行轉換。

          幸運的是,不需要編寫代碼來處理所有這些問題。這項任務已經解決了。

          JSON.stringify

          JSON(JavaScript Object Notation)是表示值和對象的通用格式。在 RFC 4627 標準中有對其的描述。最初它是為 JavaScript 而創(chuàng)建的,但許多其他編程語言也有用于處理它的庫。因此,當客戶端使用 JavaScript 而服務器端是使用 Ruby/PHP/Java 等語言編寫的時,使用 JSON 可以很容易地進行數據交換。

          JavaScript 提供了如下方法:

          • JSON.stringify 將對象轉換為 JSON。
          • JSON.parse 將 JSON 轉換回對象。

          例如,在這里我們 JSON.stringify 一個 student 對象:

          let student = {
            name: 'John',
            age: 30,
            isAdmin: false,
            courses: ['html', 'css', 'js'],
            wife: null
          };
          
          let json = JSON.stringify(student);
          
          alert(typeof json); // we've got a string!
          
          alert(json);
          /* JSON 編碼的對象:
          {
            "name": "John",
            "age": 30,
            "isAdmin": false,
            "courses": ["html", "css", "js"],
            "wife": null
          }
          */

          方法 JSON.stringify(student) 接收對象并將其轉換為字符串。

          得到的 json 字符串是一個被稱為 JSON 編碼(JSON-encoded)序列化(serialized)字符串化(stringified)編組化(marshalled) 的對象。我們現在已經準備好通過有線發(fā)送它或將其放入普通數據存儲。

          請注意,JSON 編碼的對象與對象字面量有幾個重要的區(qū)別:

          • 字符串使用雙引號。JSON 中沒有單引號或反引號。所以 'John' 被轉換為 "John"
          • 對象屬性名稱也是雙引號的。這是強制性的。所以 age:30 被轉換成 "age":30

          JSON.stringify 也可以應用于原始(primitive)數據類型。

          JSON 支持以下數據類型:

          • Objects { ... }
          • Arrays [ ... ]
          • Primitives:strings,numbers,boolean values true/falsenull

          例如:

          // 數字在 JSON 還是數字
          alert( JSON.stringify(1) ) // 1
          
          // 字符串在 JSON 中還是字符串,只是被雙引號擴起來
          alert( JSON.stringify('test') ) // "test"
          
          alert( JSON.stringify(true) ); // true
          
          alert( JSON.stringify([1, 2, 3]) ); // [1,2,3]

          JSON 是語言無關的純數據規(guī)范,因此一些特定于 JavaScript 的對象屬性會被 JSON.stringify 跳過。

          即:

          • 函數屬性(方法)。
          • Symbol 類型的屬性。
          • 存儲 undefined 的屬性。
          let user = {
            sayHi() { // 被忽略
              alert("Hello");
            },
            [Symbol("id")]: 123, // 被忽略
            something: undefined // 被忽略
          };
          
          alert( JSON.stringify(user) ); // {}(空對象)

          通常這很好。如果這不是我們想要的方式,那么我們很快就會看到如何自定義轉換方式。

          最棒的是支持嵌套對象轉換,并且可以自動對其進行轉換。

          例如:

          let meetup = {
            title: "Conference",
            room: {
              number: 23,
              participants: ["john", "ann"]
            }
          };
          
          alert( JSON.stringify(meetup) );
          /* 整個解構都被字符串化了
          {
            "title":"Conference",
            "room":{"number":23,"participants":["john","ann"]},
          }
          */

          重要的限制:不得有循環(huán)引用。

          例如:

          let room = {
            number: 23
          };
          
          let meetup = {
            title: "Conference",
            participants: ["john", "ann"]
          };
          
          meetup.place = room;       // meetup 引用了 room
          room.occupiedBy = meetup; // room 引用了 meetup
          
          JSON.stringify(meetup); // Error: Converting circular structure to JSON

          在這里,轉換失敗了,因為循環(huán)引用:room.occupiedBy 引用了 meetupmeetup.place 引用了 room

          排除和轉換:replacer

          JSON.stringify 的完整語法是:

          let json = JSON.stringify(value[, replacer, space])

          value要編碼的值。replacer要編碼的屬性數組或映射函數 function(key, value)。space用于格式化的空格數量

          大部分情況,JSON.stringify 僅與第一個參數一起使用。但是,如果我們需要微調替換過程,比如過濾掉循環(huán)引用,我們可以使用 JSON.stringify 的第二個參數。

          如果我們傳遞一個屬性數組給它,那么只有這些屬性會被編碼。

          例如:

          let room = {
            number: 23
          };
          
          let meetup = {
            title: "Conference",
            participants: [{name: "John"}, {name: "Alice"}],
            place: room // meetup 引用了 room
          };
          
          room.occupiedBy = meetup; // room 引用了 meetup
          
          alert( JSON.stringify(meetup, ['title', 'participants']) );
          // {"title":"Conference","participants":[{},{}]}

          這里我們可能過于嚴格了。屬性列表應用于了整個對象結構。所以 participants 是空的,因為 name 不在列表中。

          讓我們包含除了會導致循環(huán)引用的 room.occupiedBy 之外的所有屬性:

          let room = {
            number: 23
          };
          
          let meetup = {
            title: "Conference",
            participants: [{name: "John"}, {name: "Alice"}],
            place: room // meetup 引用了 room
          };
          
          room.occupiedBy = meetup; // room 引用了 meetup
          
          alert( JSON.stringify(meetup, ['title', 'participants', 'place', 'name', 'number']) );
          /*
          {
            "title":"Conference",
            "participants":[{"name":"John"},{"name":"Alice"}],
            "place":{"number":23}
          }
          */

          現在,除 occupiedBy 以外的所有內容都被序列化了。但是屬性的列表太長了。

          幸運的是,我們可以使用一個函數代替數組作為 replacer

          該函數會為每個 (key,value) 對調用并返回“已替換”的值,該值將替換原有的值。如果值被跳過了,則為 undefined

          在我們的例子中,我們可以為 occupiedBy 以外的所有內容按原樣返回 value。為了 occupiedBy,下面的代碼返回 undefined

          let room = {
            number: 23
          };
          
          let meetup = {
            title: "Conference",
            participants: [{name: "John"}, {name: "Alice"}],
            place: room // meetup 引用了 room
          };
          
          room.occupiedBy = meetup; // room 引用了 meetup
          
          alert( JSON.stringify(meetup, function replacer(key, value) {
            alert(`${key}: ${value}`);
            return (key == 'occupiedBy') ? undefined : value;
          }));
          
          /* key:value pairs that come to replacer:
          :             [object Object]
          title:        Conference
          participants: [object Object],[object Object]
          0:            [object Object]
          name:         John
          1:            [object Object]
          name:         Alice
          place:        [object Object]
          number:       23
          */

          請注意 replacer 函數會獲取每個鍵/值對,包括嵌套對象和數組項。它被遞歸地應用。replacer 中的 this 的值是包含當前屬性的對象。

          第一個調用很特別。它是使用特殊的“包裝對象”制作的:{"": meetup}。換句話說,第一個 (key, value) 對的鍵是空的,并且該值是整個目標對象。這就是上面的示例中第一行是 ":[object Object]" 的原因。

          這個理念是為了給 replacer 提供盡可能多的功能:如果有必要,它有機會分析并替換/跳過整個對象。

          格式化:space

          JSON.stringify(value, replacer, spaces) 的第三個參數是用于優(yōu)化格式的空格數量。

          以前,所有字符串化的對象都沒有縮進和額外的空格。如果我們想通過網絡發(fā)送一個對象,那就沒什么問題。space 參數專門用于調整出更美觀的輸出。

          這里的 space = 2 告訴 JavaScript 在多行中顯示嵌套的對象,對象內部縮緊 2 個空格:

          let user = {
            name: "John",
            age: 25,
            roles: {
              isAdmin: false,
              isEditor: true
            }
          };
          
          alert(JSON.stringify(user, null, 2));
          /* 兩個空格的縮進:
          {
            "name": "John",
            "age": 25,
            "roles": {
              "isAdmin": false,
              "isEditor": true
            }
          }
          */
          
          /* 對于 JSON.stringify(user, null, 4) 的結果會有更多縮進:
          {
              "name": "John",
              "age": 25,
              "roles": {
                  "isAdmin": false,
                  "isEditor": true
              }
          }
          */

          spaces 參數僅用于日志記錄和美化輸出。

          自定義 “toJSON”

          toString 進行字符串轉換,對象也可以提供 toJSON 方法來進行 JSON 轉換。如果可用,JSON.stringify 會自動調用它。

          例如:

          let room = {
            number: 23
          };
          
          let meetup = {
            title: "Conference",
            date: new Date(Date.UTC(2017, 0, 1)),
            room
          };
          
          alert( JSON.stringify(meetup) );
          /*
            {
              "title":"Conference",
              "date":"2017-01-01T00:00:00.000Z",  // (1)
              "room": {"number":23}               // (2)
            }
          */

          在這兒我們可以看到 date (1) 變成了一個字符串。這是因為所有日期都有一個內置的 toJSON 方法來返回這種類型的字符串。

          現在讓我們?yōu)閷ο?room 添加一個自定義的 toJSON

          let room = {
            number: 23,
            toJSON() {
              return this.number;
            }
          };
          
          let meetup = {
            title: "Conference",
            room
          };
          
          alert( JSON.stringify(room) ); // 23
          
          alert( JSON.stringify(meetup) );
          /*
            {
              "title":"Conference",
              "room": 23
            }
          */

          正如我們所看到的,toJSON 既可以用于直接調用 JSON.stringify(room) 也可以用于當 room 嵌套在另一個編碼對象中時。

          JSON.parse

          要解碼 JSON 字符串,我們需要另一個方法 JSON.parse。

          語法:

          let value = JSON.parse(str, [reviver]);

          str要解析的 JSON 字符串。reviver可選的函數 function(key,value),該函數將為每個 (key, value) 對調用,并可以對值進行轉換。

          例如:

          // 字符串化數組
          let numbers = "[0, 1, 2, 3]";
          
          numbers = JSON.parse(numbers);
          
          alert( numbers[1] ); // 1

          對于嵌套對象:

          let userData = '{ "name": "John", "age": 35, "isAdmin": false, "friends": [0,1,2,3] }';
          
          let user = JSON.parse(userData);
          
          alert( user.friends[1] ); // 1

          JSON 可能會非常復雜,對象和數組可以包含其他對象和數組。但是它們必須遵循相同的 JSON 格式。

          以下是手寫 JSON 時的典型錯誤(有時我們必須出于調試目的編寫它):

          let json = `{
            name: "John",                     // 錯誤:屬性名沒有雙引號
            "surname": 'Smith',               // 錯誤:值使用的是單引號(必須使用雙引號)
            'isAdmin': false                  // 錯誤:鍵使用的是單引號(必須使用雙引號)
            "birthday": new Date(2000, 2, 3), // 錯誤:不允許使用 "new",只能是裸值
            "friends": [0,1,2,3]              // 這個沒問題
          }`;

          此外,JSON 不支持注釋。向 JSON 添加注釋無效。

          還有另一種名為 JSON5 的格式,它允許未加引號的鍵,也允許注釋等。但這是一個獨立的庫,不在語言的規(guī)范中。

          常規(guī)的 JSON 格式嚴格,并不是因為它的開發(fā)者很懶,而是為了實現簡單,可靠且快速地實現解析算法。

          使用 reviver

          想象一下,我們從服務器上獲得了一個字符串化的 meetup 對象。

          它看起來像這樣:

          // title: (meetup title), date: (meetup date)
          let str = '{"title":"Conference","date":"2017-11-30T12:00:00.000Z"}';

          ……現在我們需要對它進行 反序列(deserialize),把它轉換回 JavaScript 對象。

          讓我們通過調用 JSON.parse 來完成:

          let str = '{"title":"Conference","date":"2017-11-30T12:00:00.000Z"}';
          
          let meetup = JSON.parse(str);
          
          alert( meetup.date.getDate() ); // Error!

          啊!報錯了!

          meetup.date 的值是一個字符串,而不是 Date 對象。JSON.parse 怎么知道應該將字符串轉換為 Date 呢?

          讓我們將 reviver 函數傳遞給 JSON.parse 作為第二個參數,該函數按照“原樣”返回所有值,但是 date 會變成 Date

          let str = '{"title":"Conference","date":"2017-11-30T12:00:00.000Z"}';
          
          let meetup = JSON.parse(str, function(key, value) {
            if (key == 'date') return new Date(value);
            return value;
          });
          
          alert( meetup.date.getDate() ); // 現在正常運行了!

          順便說一下,這也適用于嵌套對象:

          let schedule = `{
            "meetups": [
              {"title":"Conference","date":"2017-11-30T12:00:00.000Z"},
              {"title":"Birthday","date":"2017-04-18T12:00:00.000Z"}
            ]
          }`;
          
          schedule = JSON.parse(schedule, function(key, value) {
            if (key == 'date') return new Date(value);
            return value;
          });
          
          alert( schedule.meetups[1].date.getDate() ); // 正常運行了!

          總結

          • JSON 是一種數據格式,具有自己的獨立標準和大多數編程語言的庫。
          • JSON 支持 object,array,string,number,boolean 和 null
          • JavaScript 提供序列化(serialize)成 JSON 的方法 JSON.stringify 和解析 JSON 的方法 JSON.parse。
          • 這兩種方法都支持用于智能讀/寫的轉換函數。
          • 如果一個對象具有 toJSON,那么它會被 JSON.stringify 調用。

          午辦公室暖氣很熱,大家的工作狀態(tài)都不是特別好,感覺每個人都像樹懶一樣或緩慢移動鼠標、或懶懶的打著瞌睡。小白也不在狀態(tài)呆呆的盯著電腦,不知道該做些什么。經過一陣陣朦朧的困感之后,小白還是起身找到了老朱。

          “朱哥,下午實在沒狀態(tài),有沒有簡單點的知識,給我說一個唄!”

          老朱也不在狀態(tài),布局方面的實在是不想說,思考了半天說道:“要不說一下JSON數據吧,這個簡單,你只要了解了JSON數據接下來就可以說前端和后臺通信的事了。”

          “好啊!”,小白一聽終于能做通信方面的事情后,腦袋一下清醒了不少。

          老朱說:“JSON數據可以看作是對象的字符串形式。”

          “既然有了對象Object還要JSON干嘛呢?”,小白問道。

          “通過JSON串我們可以很方便的進行數據通信,比如通過ajax去加載一個頁面,被加載的頁面如果沒有html標簽只有JSON格式的字符串,我們就可以把JSON串轉換為JavaScript對象輕松進行數據處理了。”

          “聽得有點暈!”

          “你可以想象一下,你的個人信息都在數據庫存著,有一個php頁面可以把你的信息從數據取出來,現在讓你通過js獲取用戶信息,你怎么辦?”

          “是不是通過JS加載獲取用戶信息的那個php頁面?”

          老朱說道:“沒錯,那你是希望php頁面給你輸出一個含有用戶信息、html標簽和CSS的,還是返回你的昵稱、電話、頭像信息你再在前端通過JS進行處理?”

          “肯定是后者啊,這樣我就能把用戶信息放到頁面任意想放的位置了。還有一個好處,只有用戶的信息的數據字符串長度非常小,也有利于訪問速度。”

          “恩,理解的不錯!就是這個意思。實際開發(fā)的時候JSON串不會像我們現在定義的JSON串那樣簡單,如果我們要獲取一個文章列表頁的JSON串,它里面可能會包含欄目的id、欄目標題、文章列表(可能會是一個數組,也可能是一個列表對象)、每頁顯示條數、文章總數、用戶信息(一個對象,它里面又包含用戶的昵稱、電話、頭像等)。”

          “一般從外部加載的JSON串JavaScript會自動把JSON串轉換為Object對象,如果是自定義的JSON字符串我們需要使用JSON.parse(JSON串)進行兌現轉換。現在我們把剛剛定義的jstr串轉換為對象控制臺輸出看一下。”

          “最近一兩天我們嘗試做一次外部數據加載,看看你能不能理解,如果能理解我們就可以從一個小項目開始練習了。”

          小白高興的說道:“好啊!太期待了!”

          最后給大家推薦一個前端內部學習群:675498134,進群找管理免費領取學習資料和視頻。每天還是技術大牛直播分享前端項目開發(fā)經驗。大佬小白都歡迎,大家一起學習共同進步!


          主站蜘蛛池模板: 亚欧色一区W666天堂| 在线观看日韩一区| 亚洲一区免费视频| 国产婷婷色一区二区三区| 日韩免费观看一区| 人妻少妇精品一区二区三区| 狠狠色婷婷久久一区二区| 日韩一区二区三区无码影院| 中文字幕一区二区三区人妻少妇 | 国产成人无码精品一区二区三区| 国产精品自拍一区| 国产精久久一区二区三区| 亚洲国产综合精品一区在线播放| 国产午夜精品一区二区三区嫩草| 久久毛片一区二区| 一区二区三区内射美女毛片| 国产一区二区福利| 女人和拘做受全程看视频日本综合a一区二区视频 | 亚洲AV网一区二区三区| 狠狠爱无码一区二区三区| 国产精品区一区二区三在线播放| 国产主播一区二区三区在线观看| 一区二区三区电影在线观看| 亚洲综合无码一区二区痴汉| 久久精品免费一区二区三区| 成人毛片无码一区二区| 精品无人区一区二区三区| 人妻少妇精品一区二区三区| 色一情一乱一伦一区二区三区| 亚洲国产精品无码第一区二区三区| 无码人妻精品一区二区三区在线 | 文中字幕一区二区三区视频播放 | 亚洲综合一区二区| 中文字幕av无码一区二区三区电影| 日本精品一区二区在线播放| 麻豆AV一区二区三区久久| 国模无码人体一区二区| 国产一区二区三区电影| 国产免费一区二区三区VR| 午夜视频在线观看一区二区| 亚洲一区二区三区免费观看|