Working with JSON data

2018-05-15 17:26 更新
先決條件: 基本的計算機素養(yǎng),對HTML和CSS的基本了解,熟悉JavaScript基礎知識(請參見第一步構(gòu)建塊 / a>)和OOJS基礎知識(請參見對象簡介)。
目的: 要了解如何使用存儲在JSON中的數(shù)據(jù),并創(chuàng)建自己的JSON對象。

不,真的,什么是JSON?

JSON 是一種數(shù)據(jù)格式,遵循JavaScript對象語法,該語法由 a class ="external"> Douglas Crockford 。 即使它是基于JavaScript語法,它可以獨立于JavaScript使用,并且許多編程環(huán)境具有讀取(解析)和生成JSON的能力。

JSON可以作為對象或字符串存在 - 前者用于從JSON讀取數(shù)據(jù),后者用于在網(wǎng)絡上發(fā)送JSON。 這不是一個大問題 - JavaScript提供了一個全局 JSON 對象 有可用于在兩者之間轉(zhuǎn)換的方法。

JSON對象可以存儲在自己的文件中,基本上只是一個擴展名為 .json mozilla.org/zh-CN/docs/Glossary/MIME_type\"> MIME類型 application / json

JSON結(jié)構(gòu)

我們在上面已經(jīng)暗示,JSON對象基本上是一個JavaScript對象,這是最正確的。 您可以在JSON中包含與標準JavaScript對象(字符串,數(shù)字,數(shù)組,布爾值和其他對象字面值)中相同的基本數(shù)據(jù)類型。 這允許您構(gòu)造數(shù)據(jù)層次結(jié)構(gòu),如下所示:

{
? "squadName" : "Super hero squad",
? "homeTown" : "Metro City",
? "formed" : 2016,
? "secretBase" : "Super tower",
  "active" : true,
? "members" : [
??? {
????? "name" : "Molecule Man",
????? "age" : 29,
????? "secretIdentity" : "Dan Jukes",
????? "powers" : [
??????? "Radiation resistance",
??????? "Turning tiny",
??????? "Radiation blast"
????? ]
??? },
??? {
????? "name" : "Madame Uppercut",
????? "age" : 39,
????? "secretIdentity" : "Jane Wilson",
????? "powers" : [
??????? "Million tonne punch",
??????? "Damage resistance",
??????? "Superhuman reflexes"
????? ]
??? },
??? {
????? "name" : "Eternal Flame",
????? "age" : 1000000,
????? "secretIdentity" : "Unknown",
????? "powers" : [
??????? "Immortality",
??????? "Heat Immunity",
??????? "Inferno",
??????? "Teleportation",
??????? "Interdimensional travel"
????? ]
??? }
? ]
}

如果我們將這個對象加載到JavaScript程序中,保存在一個叫做 superHeroes 的變量中,我們就可以使用我們在 "/ webstart / Objects / Basics"> JavaScript對象基礎文章。 例如:

superHeroes.hometown
superHeroes["active"]

要在層次結(jié)構(gòu)中進一步訪問數(shù)據(jù),您只需將所需的屬性名稱和數(shù)組索引鏈接在一起。 例如,要訪問成員列表中列出的第二個英雄的第三超級大國,您可以這樣做:

superHeroes["members"][1]["powers"][2]
  1. First we have the variable name — superHeroes.
  2. Inside that we want to access the members property, so we use ["members"].
  3. members contains an array populated by objects. We want to access the second object inside the array, so we use [1].
  4. Inside this object, we want to access the powers property, so we use ["powers"].
  5. Inside the powers property is an array containing the selected hero's superpowers. We want the third one, so we use [2].

注意:我們已在上面的 /json/JSONTest.html\">JSONText.html 示例(請參閱 /json/JSONTest.html\">源代碼)。 嘗試加載,然后通過瀏覽器的JavaScript控制臺訪問變量中的數(shù)據(jù)。

數(shù)組為JSON

上面我們說"我們已經(jīng)暗示JSON對象基本上是一個JavaScript對象,這是正確的" - 我們說"大多數(shù)正確"的原因是因為數(shù)組也可以是一個有效的JSON對象,例如:

[
  {
    "name" : "Molecule Man",
    "age" : 29,
    "secretIdentity" : "Dan Jukes",
    "powers" : [
      "Radiation resistance",
      "Turning tiny",
      "Radiation blast"
    ]
  },
  {
??? "name" : "Madame Uppercut",
??? "age" : 39,
??? "secretIdentity" : "Jane Wilson",
??? "powers" : [
????? "Million tonne punch",
????? "Damage resistance",
????? "Superhuman reflexes"
??? ]
? }
]

上面是完全有效的JSON。 你只需要從數(shù)組索引開始訪問數(shù)組項,例如 [0] ["powers"] [0] 。

其他說明

  • JSON is purely a data format — it contains only properties, no methods.
  • JSON requires double quotes to be used to be valid. It is safest to write it with double quotes, not single quotes.
  • Even a single misplaced comma or colon can cause a JSON file to go wrong, and not work. You should be careful to validate any data you are attempting to use (although computer-generated JSON is less likely to include errors, as long as the generator program is working correctly). You can validate JSON using an application like JSONLint.
  • JSON can actually take the form of any data type that is valid for inclusion inside a standard JSON object, not just arrays or objects. So for example, a single string or number would be a valid JSON object. Not that this would be particularly useful...

主動學習:通過JSON示例

因此,讓我們通過一個例子來說明如何在網(wǎng)站上使用一些JSON數(shù)據(jù)。

入門

首先,制作我們的英雄的本地副本。 html 和 style.css a>文件。 后者包含一些簡單的CSS來為我們的頁面設計樣式,而前者包含一些非常簡單的body HTML:

<header>
</header>

<section>
</section>

加上 < script> 元素,以包含我們將在此處撰寫的JavaScript代碼 行使。 目前它只包含兩行,它們引用了 < header> < section> 元素并將其存儲在變量中:

var header = document.querySelector('header');
var section = document.querySelector('section');

我們已將我們的JSON數(shù)據(jù)提供給我們的GitHub,網(wǎng)址為: https:/ /mdn.github.io/learning-area/javascript/oojs/json/superheroes.json 。

我們將把它加載到我們的頁面,并使用一些漂亮的DOM操作來顯示它,像這樣:

加載我們的JSON

要將我們的JSON加載到我們的網(wǎng)頁中,我們將使用名為 XMLHttpRequest 的API(通常稱為 XHR )。 這是一個非常有用的JavaScript對象,它允許我們通過JavaScript(例如圖像,文本,JSON,甚至HTML片段)來從服務器檢索資源,這意味著我們可以更新內(nèi)容的小部分,而不必重新加載整個 頁。 這導致更響應的網(wǎng)頁,并聽起來令人興奮,但不幸的是超出了本文的范圍,教更多的細節(jié)。

  1. To start with, we are going to store the URL of the JSON file we want to retrieve in a variable. Add the following at the bottom of your JavaScript code:
    var requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
  2. To create a request, we need to create a new request object instance from the XMLHttpRequest constructor, using the new keyword. Add the following below your last line:
    var request = new XMLHttpRequest();
  3. Now we need to open a new request using the open() method. Add the following line:
    request.open('GET', requestURL);

    這至少需要兩個參數(shù) - 還有其他可選參數(shù)可用。 對于這個簡單的例子,我們只需要兩個強制的:

    • The HTTP method to use when making the network request. In this case GET is fine, as we are just retrieving some simple data.
    • The URL to make the request to — this is the URL of the JSON file that we stored earlier.
  4. Next, add the following two lines — here we are setting the responseType to JSON, so the server will know we want a JSON object returned, and sending the request with the send() method:
    request.responseType = 'json';
    request.send();
  5. The last bit of this section involves waiting for the response to return from the server, then dealing with it. Add the following code below your previous code:
    request.onload = function() {
      var superHeroes = request.response;
      populateHeader(superHeroes);
      showHeroes(superHeroes);
    }

這里我們存儲對我們的請求的響應(可在 響應 > 屬性)在一個名為 superHeroes 的變量中; 這個變量現(xiàn)在將包含我們的JSON! 然后,我們將該JSON傳遞給兩個函數(shù)調(diào)用 - 第一個將用正確的數(shù)據(jù)填充< header> ,而第二個將為團隊中的每個英雄創(chuàng)建一個信息卡, 將其插入到< section> 中。

我們將代碼包裝在事件處理程序中,當load事件觸發(fā)請求對象時運行(參見 XMLHttpRequestEventTarget / onload"> onload ) - 這是因為load事件在響應成功返回時觸發(fā); 這樣做保證 request.response 一定會可用,當我們試圖做一些事情。

填充頭

現(xiàn)在我們已經(jīng)檢索了我們的JSON數(shù)據(jù),讓我們通過寫我們上面提到的兩個函數(shù)來使用它。 首先,在上面的代碼下面添加以下函數(shù)定義:

function populateHeader(jsonObj) {
  var myH1 = document.createElement('h1');
  myH1.textContent = jsonObj['squadName'];
  header.appendChild(myH1);

  var myPara = document.createElement('p');
  myPara.textContent = 'Hometown: ' + jsonObj['homeTown'] + ' // Formed: ' + jsonObj['formed'];
  header.appendChild(myPara);
}

我們調(diào)用了參數(shù) jsonObj ,這就是我們需要調(diào)用它里面的JSON對象。 在這里,我們首先使用創(chuàng)建 < h1> 元素 > createElement() ,將其 > textContent 等于 squadName 屬性 JSON,然后使用 appendChild()將其附加到標題 。 然后,我們對一個段落進行非常類似的操作:創(chuàng)建它,設置其文本內(nèi)容并將其附加到標題。 唯一的區(qū)別是其文本設置為包含JSON的 homeTown 形成屬性的連接字符串。

創(chuàng)建英雄信息卡

接下來,在代碼的底部添加以下函數(shù),創(chuàng)建并顯示超級英雄卡:

function showHeroes(jsonObj) {
  var heroes = jsonObj['members'];
      
  for(i = 0; i < heroes.length; i++) {
    var myArticle = document.createElement('article');
    var myH2 = document.createElement('h2');
    var myPara1 = document.createElement('p');
    var myPara2 = document.createElement('p');
    var myPara3 = document.createElement('p');
    var myList = document.createElement('ul');

    myH2.textContent = heroes[i].name;
    myPara1.textContent = 'Secret identity: ' + heroes[i].secretIdentity;
    myPara2.textContent = 'Age: ' + heroes[i].age;
    myPara3.textContent = 'Superpowers:';
        
    var superPowers = heroes[i].powers;
    for(j = 0; j < superPowers.length; j++) {
      var listItem = document.createElement('li');
      listItem.textContent = superPowers[j];
      myList.appendChild(listItem);
    }

    myArticle.appendChild(myH2);
    myArticle.appendChild(myPara1);
    myArticle.appendChild(myPara2);
    myArticle.appendChild(myPara3);
    myArticle.appendChild(myList);

    section.appendChild(myArticle);
  }
}

首先,我們將JSON的 members 屬性存儲在一個新變量中。 此數(shù)組包含多個對象,其中包含每個英雄的信息。

接下來,我們使用 for循環(huán)循環(huán)訪問數(shù)組中的每個對象。 對于每一個,我們:

  1. Create several new elements: an <article>, an <h2>, three <p>s, and a <ul>.
  2. Set the <h2> to contain the current hero's name.
  3. Fill the three paragraphs with their secretIdentity, age, and a line saying "Superpowers:" to introduce the information in the list.
  4. Store the powers property in another new variable called superPowers — this contains an array that lists the current hero's superpowers.
  5. Use another for loop to loop through the current hero's superpowers — for each one we create a <li> element, put the superpower inside it, then put the listItem inside the <ul> element (myList) using appendChild().
  6. The very last thing we do is to append the <h2>, <p>s, and <ul> inside the <article> (myArticle), then append the <article> inside the <section>. The order in which things are appended is important, as this is the order they will be displayed inside the HTML.

注意:如果您在使用我們用于訪問JSON的點/括號符號時遇到問題,可以使用 github.io/learning-area/javascript/oojs/json/superheroes.json\">superheroes.json 文件在另一個選項卡或文本編輯器中打開,并在查看我們的JavaScript時參考它。 您還應參閱我們的 JavaScript對象基礎知識文章,了解點和括號符號的更多信息。

在對象和文本之間轉(zhuǎn)換

上面的例子在訪問JSON方面很簡單,因為我們設置XHR以JSON格式返回響應,使用:

request.responseType = 'json';

但有時我們不那么幸運 - 有時我們會收到一些格式化為文本字符串的JSON數(shù)據(jù),我們需要將它轉(zhuǎn)換為一個對象。 當我們想要發(fā)送JSON數(shù)據(jù)作為某種消息時,我們經(jīng)常需要將其轉(zhuǎn)換為字符串,以使其正常工作。 幸運的是,這兩個問題在Web開發(fā)中非常常見,內(nèi)置的 JSON / a>對象被添加到瀏覽器很久以前,包含以下兩種方法:

  • parse(): Accepts a JSON object in text string form as a parameter, and returns the corresponding object.
  • stringify(): Accepts a JSON object as a parameter, and returns the equivalent text string form.

您可以在我們的 > heroes-finished-json-parse.html example(see the json / heroes-finished-json-parse.html">源代碼) - 這與我們之前構(gòu)建的示例完全相同,只是我們設置XHR將JSON作為文本返回,然后使用 parse()將其轉(zhuǎn)換為實際的JSON對象。 代碼的關鍵代碼片段在這里:

request.open('GET', requestURL);
request.responseType = 'text'; // now we're getting a string!
request.send();

request.onload = function() {
  var superHeroesText = request.response; // get the string from the response
  var superHeroes = JSON.parse(superHeroesText); // convert it to an object
  populateHeader(superHeroes);
  showHeroes(superHeroes);
}

正如你可能猜到的, stringify()工作方式相反。 嘗試在瀏覽器的JavaScript控制臺中輸入以下行,以便在操作中查看它:

var myJSON = { "name" : "Chris", "age" : "38" };
myJSON
var myString = JSON.stringify(myJSON);
myString

這里我們創(chuàng)建一個JSON對象,然后檢查它包含什么,然后使用 stringify()將返回值保存在一個新的變量,然后再次檢查它轉(zhuǎn)換為字符串。

概要

在本文中,我們?yōu)槟峁┝嗽诔绦蛑惺褂肑SON的簡單指南,包括如何創(chuàng)建和解析JSON,以及如何訪問其中鎖定的數(shù)據(jù)。 在下一篇文章中,我們將開始討論面向?qū)ο蟮腏avaScript。

也可以看看

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號