この翻訳は不完全です。英語から この記事を翻訳 してください。

JavaScript Object Notation (JSON) は表現用の標準的なテキストベースの構造データ表現フォーマットで、JavaScript構造データオブジェクトの表記法をベースとしています。一般的にはWebアプリケーションでデータを転送する場合に使われます。(例えば、データをサーバからクライアントへ送信する場合などで、Webページに表示されたりすることもあり、その逆もあります)。頻繁に見かけるデータフォーマットですので、この節ではJavaScriptを使ってJSONをパースする、JSONのデータを参照する、JSONを作るなど、JSONを扱うために必要となる操作を説明します。

前提条件: 基礎的なコンピュータの知識、 HTMLとCSSへの基本的な理解、基礎的なJavaScriptの理解 (JavaScriptの第一歩JavaScriptの構成要素を参照) とオブジェクト指向JavaScriptの基本 (JavaScriptオブジェクトの基本を参照)。
目的: JSON内のデータの扱い方、JSONの作成方法について理解できること。

JSONとは何か

JSON はJavaScriptオブジェクトの構文に従ったテキストベースのフォーマットで、Douglas Crockfordによって普及されました。JSONはJavaScriptオブジェクトの構文に似ていますが、JavaScriptとは独立して扱われることがあり、多くのプログラミング言語環境にはJSONを読み込む(パースする)ことや生成するが機能があります。

JSONは文字列です。ですので、ネットワークを通してデータを転送したい場合に便利です。JSONデータへアクセスしたい場合は、JavaScriptオブジェクトへ変換する必要があります。JavaScriptにはJSONとJavaScriptオブジェクトを相互に変換できるメソッドを持ったJSONというグローバルなオブジェクトがあるので、その変換は大きな問題ではありません。

注記: 文字列をネイティブオブジェクトへ変換することはparsingと呼ばれており、ネイティブオブジェクトをネットワークを通して転送できように文字列へ変換することはstringificationと呼ばれています。

JSONはそれ自身をファイルとして格納することもできます。それはMIME typeapplication/jsonで、 .json という拡張子の付いたただのテキストファイルです。

JSONの構造

上で説明したように、JSONはJavaScriptオブジェクトにとても似ているフォーマットを持った文字列です。JSONでは通常のJavaScriptオブジェクトと同様な基本データ型(文字列、数値、配列、ブーリアンやその他のリテラル型)を使うことができます。これにより、以下のように階層的にデータを構成することができます。

{
  "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へ代入する)、JavaScript オブジェクトの基本の節で見たのと同様に ドットや角括弧を使ってデータへアクセスすることができます。例としては以下のようになります。

superHeroes.homeTown
superHeroes['active']

さらに深い階層のデータへアクセスする場合は、単純にプロパティ名や配列のインデックスを連結します。例えば、メンバーリスト中2番目のヒーローの3番目の能力を参照する場合は、以下のようになります。

superHeroes['members'][1]['powers'][2]
  1. まず、変数名superHeroesを指定します。
  2. その中のmembersプロパティへアクセスしたいので、["members"]と指定します。
  3. membersにはオブジェクトの配列が格納されています. ここでは、配列内の2番目のオブジェクトへアクセスするので、[1]を指定します。
  4. そのオブジェクト内で、powers プロパティへアクセスするため, ["powers"]と指定します。
  5. powersプロパティは選択したヒーローの能力を含んだ配列となっており、その中の3番目が欲しいので、[2]と記述します。

注記: 上記のJSONはJSONTest.html で参照することができます。(ページ内のsource codeを参照してください)。ページを読み込んで見て、ブラウザのコンソールで変数内のデータにアクセスしてみてください。

JSON配列

ここまで見てきたように、JSONはJavaScriptオブジェクトとほとんど同じように扱うことができます。配列も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であり、パースしたデータには配列のインデックスを指定するだけです。例えば、[0]["powers"][0]のように表記できます。

その他の注意点

  • JSONはただのデータフォーマットなので、プロパティのみを含むことができ、メソッドを含むことができません。
  • JSONでは文字列とプロパティ名をダブルクォートで括る必要があります。シングルクォートで括ることはできません。
  • 1つだけコンマやコロンが抜けているだけで無効なJSONになりえます。なので、使用しているデータが有効であるかについては注意してみなければなりません(機械的に作ったJSONのほうが、プログラムに問題がなければ、エラーは少なく済みます)。 JSONLint のようなアプリケーションを使ってバリデートすることもできます。
  • JSONは配列やオブジェクトに限らずJSON内に含むことができるデータ型のデータだけでも有効なJSONとなります。 例えば、1つだけの文字列や数値も有効なJSONです。

手を動かして学ぼう: JSONをさわってみる

それでは、Webサイト上でどのようにJSONを使うことができるか例を通して見てみましょう。

はじめに

まず、heroes.html と style.css のコピーをローカルに作成してください。後者は例題ページをスタイリングするためのCSSであり、前者は簡単な形式のHTMLです。

<header>
</header>

<section>
</section>

他には、この演習で書くJavaScriptを含んだ<script>要素があります。この時点では、<header>要素と<section>要素 を取得して、変数へ代入している2行コードのみが書かれています。

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

演習用のJSONデータはhttps://mdn.github.io/learning-area/javascript/oojs/json/superheroes.jsonに用意してあります。

そのデータを演習ページに読み込んで、それを表示するのにいくらかのDOM操作を行います。最終的には、以下の画像のようになります。

JSONの取得

JSONを取得するために、XMLHttpRequest (XHR) と呼ばれるAPIを使います。このAPIはJavaScript経由でサーバーからリソース(画像、テキスト、JSON、HTMLスニペットなど)を取得するのにとても便利なオブジェクトです。つまり、ページ全体を再読み込みせずに、ページの一部のみを更新することができます。このAPIで、より反応性のあるページを作れますし、とてもおもしろそうですが、残念なことに、より詳細なことはこの記事の範疇を超えてしまっています。

  1. まず、取得したいJSONがあるURLを変数へ代入します。次のコードをJavaScriptの最後の行へ追加してください。
  2. var requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
  3. HTTPリクエストを作成するのに、new を使ってXMLHttpRequestから新しいリクエストオブジェクトをつくる必要があります。先ほどのコードの下に、次のコードを追加してください。
    var request = new XMLHttpRequest();
  4. 新しいリクエストを開始するのにはopen() メソッドを使います。 次のコードを追加してください。
    request.open('GET', requestURL);

    このメソッドは最低2つのパラメータを引数として取ります(他に任意の引数を与えることもできます)。今回の簡単な例では、次の2つの必須パラメータのみを利用します。

    • リクエストを開始する際にHTTPのメソッドを決める必要があります。今回のケースでは、単純にデータを取得するだけですのでGETが良いでしょう。
    • リクエストを送る先のURL。今回はJSONファイルが置かれているURLです。
  5. 次に、以下の2行のコードを追加してください。XHRオブジェクトがサーバから返されるデータを判断できるようにresponseTypeにJSONを指定します。すると、ブラウザ側でJavaScriptオブジェクトへ変換してくれます。それから、send() メソッドでリクエストを送信します。
    request.responseType = 'json';
    request.send();
  6. 最後に、サーバからのレスポンスを待ち、それを処理するコードを用意するので、以下のコードをこれまでのコードの下に追加してください。
    request.onload = function() {
      var superHeroes = request.response;
      populateHeader(superHeroes);
      showHeroes(superHeroes);
    }

ここでは、先ほどのリクエストに対するレスポンス(response プロパティから取得できます)をsuperHeroesという変数へ代入しています。つまり、この変数にJSONを元にに生成されたJavaScriptオブジェクトが格納されているということです! それから2つの関数をそのオブジェクトを引数として与えて呼び出しています。最初の関数は引数のデータを<header> へ埋め込み、2つ目は各ヒーローごとのインフォメーションカードを作り、<section>へ埋め込みます。

上記の処理は、リクエストオブジェクトでloadイベントが発生した時に呼び出される関数(onloadを参照) に記述しました。このイベントはレスポンスがうまく取得できた場合に呼び出されるので、 request.responseを使って何か処理をしようとしたときに、それが必ず利用できることが保証されています。

ヘッダーへの値のセット

ここまでで、JSONの取得とJavaScriptオブジェクトへの変換ができました、先ほどの2つの関数を実装して使ってみましょう。まずはじめに、以下のコードをこれまでのコードの下に追加してください。

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);
}

JSONから変換したJavaScriptオブジェクトであるjsonObjを使います。まず、createElement()<h1> 要素を生成、そのtextContent プロパティにJSONのsquadNameプロパティをセット、それをヘッダー要素でappendChild()追加します。次には、要素の生成、テキストのセット、ヘッダ要素への追加という同じような操作をパラグラフ要素でも行います。セットするテキストの値がhomeTownformed プロパティの文字列を結合したものであるという点だけが異なります。

ヒーローインフォメーションカードの作成

次に、以下の関数をコードの下へ追記してください。この関数はスーパーヒーローカードの作成と画面表示を行います。

function showHeroes(jsonObj) {
  var heroes = jsonObj['members'];
      
  for (var 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 (var 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);
  }
}

To start with, we store the members property of the JavaScript object in a new variable. This array contains multiple objects that contain the information for each hero.

Next, we use a for loop to loop through each object in the array. For each one, we:

  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.

Note: If you are having trouble getting the example to work, try referring to our heroes-finished.html source code (see it running live also.)

Note: If you are having trouble following the dot/bracket notation we are using to access the JavaScript object, it can help to have the superheroes.json file open in another tab or your text editor, and refer to it as you look at our JavaScript. You should also refer back to our JavaScript object basics article for more information on dot and bracket notation.

Converting between objects and text

The above example was simple in terms of accessing the JavaScript object, because we set the XHR request to convert the JSON response directly into a JavaScript object using:

request.responseType = 'json';

But sometimes we aren't so lucky — sometimes we'll receive a raw JSON string, and we'll need to convert it to an object ourselves. And when we want to send a JavaScript object across the network, we'll need to convert it to JSON (a string) before sending. Luckily, these two problems are so common in web development that a built-in JSON object is available in browsers, which contains the following two methods:

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

You can see the first one in action in our heroes-finished-json-parse.html example (see the source code) — this does exactly the same thing as the example we built up earlier, except that we set the XHR to return the raw JSON text, then used parse() to convert it to an actual JavaScript object. The key snippet of code is here:

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);
}

As you might guess, stringify() works the opposite way. Try entering the following lines into your browser's JavaScript console one by one to see it in action:

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

Here we're creating a JavaScript object, then checking what it contains, then converting it to a JSON string using stringify() — saving the return value in a new variable — then checking it again.

まとめ

この節では、プログラム内で、JSONを生成する、JSONをパースする、JSONデータを参照するなど、JSONを扱う方法について簡単に説明しました。次の節では、オブジェクト指向JavaScriptについて見ていくことにします。

関連項目

 

このモジュール内の文書

 

ドキュメントのタグと貢献者

 このページの貢献者: r-tamura
 最終更新者: r-tamura,