【JavaScript】ゼロから始めるJSON入門

JavaScript

JSON とは、JavaScript Object Notationの略でJavaScriptのオブジェクトの表記法をベースにしたデータフォーマットのことです。

オブジェクト({})の中にダブルクォーテーション("")で囲った名前と値のペアを記述します。
名前の後にはコロン(:)がつきます。

JSONの基本構文
1
{ "名前": "値"}

複数のデータを記述する際は、以下のようにカンマ(,)で区切ります。

JSONの例
1
2
3
4
5
{
    "id": 1,
    "name": "piyoko",
    "age": 18
}

JavaScriptの表記法をベースにしていますが、JavaScript専用という訳ではなく他のプログラミング言語でも利用することが出来ます。

JSONの基本情報

この章では、JSONの基本情報について解説します。

構文
リンクをコピーしました

JSONは、以下のように記述する事で、名前: 値のペアのデータを設定する事が出来ます。

JSON | JSONの基本構文(データが1つの場合)
1
{ "名前": "値"}
JSON | JSONの基本構文(データが複数の場合)
1
2
3
4
5
{
    "名前1": "値1",
    "名前2": "値2",
    "名前3": "値3"
}

また、JSONはJavaScriptのオブジェクトの表記法がベースとなっています。

JavaScriptのオブジェクトの表記法
リンクをコピーしました

JavaScriptでオブジェクトを作成するには、{}で新しくオブジェクトを作成する事が出来ます。

JavaScriptでオブジェクトを作成する
1
const object = {}; // 空のオブジェクトを作成する

また、作成時に以下のようにオブジェクトの名前と値を記述する事で定義する事が出来ます。
左側の"名前"がオブジェクトのキー名で右側がオブジェクトのバリューです。

オブジェクトの作成と定義を同時に行う
1
2
3
4
5
6
7
const object = {
 "名前": "" //キー名: "バリュー"
};

const user1 = {
    "name": "Tanaka" // "name"がキー名で"Tanaka"がバリュー
};

キーとバリューがペアになったものをプロパティと言います。このプロパティには、オブジェクト名.プロパティのキー名オブジェクト名["プロパティのキー名"]でアクセスする事が出来ます。

オブジェクトの作成と定義を同時に行う
1
2
3
4
5
6
7
8
9
const user1 = {
    "name": "Tanaka"
};

user1.name // オブジェクト名.プロパティのキー名
> "Tanaka"

user1["name"] // オブジェクト名["プロパティのキー名"]
> "Tanaka"

そして、プロパティのキー名は、ダブルクォーテーションを省略する事が出来ます。

上記のconst user1"name": "Tanaka"は、以下のようにダブルクォテーションを省略して、name: "Tanaka"にする事ができます。

オブジェクトのキー名のダブルクォーテーションを省略する
1
2
3
4
5
6
7
8
9
const user1 = {
    name: "Tanaka" // "name": "Tanaka"と同様
};

user1.name // オブジェクト名.プロパティのキー名
> "Tanaka"

user1["name"] // オブジェクト名["プロパティのキー名"]
> "Tanaka"

ダブルクォーテーションを省略しても、プロパティにアクセスした際に"name": "Tanaka"の時と同様の結果を得る事が出来ています。

JavaScriptとJSONとの違い
リンクをコピーしました

JSONは、JavaScriptのオブジェクト表記法がベースになっていますが、プログラミング言語ではない為、各プログラムでJSONのデータを扱う際は解析・変換(パース)する必要があります。

例えば、JSON→JavaScriptJSON→Ruby, JSON→Javaなど

これにより、パースしやすい様に決められたJavaScriptのオブジェクト表記法とは異なるJSON独自の制約があります。

  • キー名は、必ずダブルクォーテーションをつける
  • バリューにゼロで始まる数値は使う事が出来ない
JavaScriptの場合
1
2
3
4
const user1 = {
    name: "Tanaka", // キー名のダブルクォーテーションを省略する事ができる
    age: 05 // 0で始まる数値を使う事ができる
};

JSONの場合は、キー名のダブルクォーテーションの省略やバリューにゼロで始まる数値は使う事が出来ないので以下のように記述します。

JSON | キー名にダブルクォーテーション追加とゼロを削除
1
2
3
4
{
    "name": "Tanaka", 
    "age": 5
}

参考:「 jsprimer JSONとは」より

JSONを記述する際の注意点
リンクをコピーしました

下記は、JSONを記述する際に陥りやすいエラーです。

エラーの原因 間違った例 正しい例
キー名をシングルクォーテーションで囲っている 'key': "value" "key": "value"
全角スペースが含まれている {"key": "value" } {"key": "value" }
プロパティの区切りにカンマ(,)がない {"key1":"value1" "key2":"value2" } {"key1":"value1", "key2":"value2" }
JavaScriptのコメント構文を使っている {"name": "Tanaka" // 名前} JSONにコメント構文はないので使えない

JSONで使える型
リンクをコピーしました

プロパティの値に使う事が出来る型には、以下の種類あります。

JSON | JSONで使う事が出来る型
1
2
3
4
5
6
7
8
9
{
    "オブジェクト": { 
        "数値": 1, 
        "文字列": "pikawaka",
        "真偽値": true,
        "null値": null,
        "配列": [1, 2, 3]
    }
}

参考:「 jsprimer JSONとは」より

  • オブジェクト - {}
  • 数値 - 1
  • 文字列 - "pikawaka"
  • 真偽値 - true, false
  • null値 - null
  • 配列 - []

それでは1つ1つの型を確認していきましょう。

数値
リンクをコピーしました

プロパティの値に123などの数値を指定する事が出来ます。

JSON | バリューに数値を使う
1
2
3
{
  "age": 18
}

数値を使う際に先ほども解説しましたが、はじめに0をつける事が出来ないのと小数点から始まる数値を使う事が出来ないので注意してください。

JSON | バリューに数値を指定する際に使えないパターン
1
2
3
4
{
  "error1": 0123,
  "error2": .324
}

構文チェックが出来るJSON Pretty Linterで確認すると、以下のようにエラーが発生します。

構文チェックに引っかかる例

文字列
リンクをコピーしました

プロパティのバリューには、ダブルクォーテーションで囲った文字列を使う事が出来ます。

JSON | バリューに文字列を使う
1
2
3
4
{
"name": "Tanaka",
 "comment": "私は平生もし同じ妨害論に対してものの中に聴こうです。はなはだ今をふり者はとうとうその説明なかっです"
}

また、文字列の中には、ダブルクォーテーション( "" )やバックスラッシュ( \ )を使う事ができません。

例えば、commentのバリューの妨害論をダブルクォーテーションで囲み、改行の\nを追加すると以下のように構文エラーになったり、改行は認識さません。

プロパティのバリューに文字列を使うとエラーになる

このようにダブルクォテーション、もしくは改行の\nでバックスラッシュを文字列の中で有効にする場合は、以下のように手前に\を配置してエスケープする必要があります。

JSON | エスケープして文字列の中にダブルクォテーションと改行を使う
1
2
3
4
{
"name": "Tanaka",
 "comment": "私は平生もし同じ\"妨害論\"に対してものの中に聴こうです。\\nはなはだ今をふり者はとうとうその説明なかっです"
}

エスケープを使用すると、以下のようにエラーが解消されます。

文字列にエスケープを使用した例

他にもエスケープが必要な文字には、スラッシュ(/)やバックスペース(\b)があるので注意してください。

null値
リンクをコピーしました

プロパティのバリューには、null値を指定する事が出来ます。null値とは、値がないことを指します。

JSON | バリューにnullを指定する
1
2
3
{
  "name": null
}

大文字になると、以下のようにエラーが発生するので注意してください。

真偽値
リンクをコピーしました

プロパティのバリューには、truefalseの真偽値を指定する事が出来ます。

JSON | バリューに真偽値を指定する
1
2
3
4
{
"is_deleted": true, 
"is_active":  false
}

truefalseは小文字だけ使う事が出来ます。大文字になると、以下のようにエラーが発生するので注意してください。

真偽値エラー

オブジェクト
リンクをコピーしました

オブジェクト({})でJSONのデータを作成していましたが、プロパティの値にもオブジェクトを使う事が出来ます。

JSON | バリューにオブジェクトを使う
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
 "Tanaka": {
    "Totalscore": 250,
    "Arithmetic": 80,
    "Science": 90,
    "Music":  80
  } ,
 "Ito": {
    "Totalscore": 230,
    "Arithmetic": 80,
    "Science": 80,
    "Music":  70
  } 
}

上記の様にバリューにオブジェクトを使うことによって、階層構造を持つ事が出来ます。

配列
リンクをコピーしました

プロパティのバリューには、配列[]を使う事が出来ます。

JSON | バリューに配列を使う
1
2
3
{
  "favorite_fruit": ["strawberry", "cherry", "watermelon"]
}

配列の要素には、文字列や数値はもちろん配列やnull値や真偽値、そしてオブジェクトを使う事が出来ます。

そして、以下のように配列の要素にオブジェクト({})を使う事で、オブジェクトのデータを順番に管理する事が出来ます。

JSON | 配列の要素にオブジェクトを使った例
1
2
3
4
5
6
7
{
  "users": [
    {"id": 1, "name": "Tanaka", "age":33 },
    {"id": 2, "name": "Yosida", "age":18 },
    {"id": 3, "name": "Tabe", "age":29 }
  ]
}

特徴
リンクをコピーしました

JSONの特徴には、主に以下の3つが挙げられます。

  • 他のプログラミング言語でも使う事が出来る
  • 軽量なデータフォーマット
  • データフォーマットとして柔軟性

ほとんどのプログラミング言語において、JSONのデータを書き出すことや読み出す事が出来ます。
また、JSONはテキストデータなのでデータ量が軽いのも特徴です。

データフォーマットとして柔軟性
リンクをコピーしました

JSONは、複雑なデータ構造を配列やオブジェクトを使って、柔軟に表現する事が出来ます。

例えば、以下のような表でユーザー管理をしている場合について考えてみます。

表でユーザー管理する場合

この表では特に問題が無さそうですが、会社用とプライベート用のemailを分けて管理したい場合は、以下のように会社のemailとプライベートのemailの列を作る必要がありますが、項目が増えるたびに横に列が増えて管理し辛くなりますし、重複した項目名が増えてややこしいくなります。

email列を会社用とプライベート用に分ける

しかし、JSONではemailを以下のようにオブジェクトを使って階層化する事で、重複した項目の種類(例: email)が増えても、管理がしやすくなります。

JSON | JSONでemailを会社とプライベートに分けた場合
1
2
3
4
5
6
7
8
9
{
  "id": 1,
  "name": "Tanaka",
  "age": 19, 
  "email": {
    "company": "example.com",
    "private": "pri-example.com"
  } 
}

JavaScriptでJSONを扱う方法

この章では、JavaScriptでJSON文字列をオブジェクトに変換したり、逆にオブジェクトをJSON文字列に変換する方法を解説します。

オブジェクトをJSON文字列に変換
リンクをコピーしました

JavaScriptのオブジェクトを JSON文字列に変換するには、以下の様にJSON.stringify()メソッドを使います。

コンソール | オブジェクトからJSON文字列に変換
1
2
 // 引数に渡したJavaScriptのオブジェクトをJSON文字列に変換する
JSON.stringify(JavaScriptのオブジェクト)

例えば、引数のJavaScriptのオブジェクトを以下のように記述します。

コンソール | JavaScriptのオブジェクトをJSON文字列に変換する
1
2
3
4
const user_object = { id: 1, name: "Tanaka", age: 19 }

JSON.stringify(user_object)
> "{"id":1,"name":"Tanaka","age":19}"

上記のコンソールで実行すると、キー名が全てダブルクォーテーションで囲われたJSON文字列が返却されます。

JSON文字列が返る

これは、JavaScriptとJSONとの違いで解説しましたが、JSONでは、ダブルクォーテーションでキー名を囲わなければならないなどの独自の仕様がある為です。

JSON形式に変換出来ないオブジェクト
リンクをコピーしました

オブジェクトの値がSymbol関数のプロパティの場合は、JSON形式に変換する事が出来ないので注意してください。

コンソール | JSON形式に変換出来ないオブジェクト
1
2
3
4
5
// プロパティの値がシンボルの場合
JSON.stringify({ test1: Symbol("") })

// プロパティの値が関数の場合
JSON.stringify({ test2: function() {} })

上記のコードをコンソールで実行すると、以下のようにJSON文字列に変換されていない事がわかります。

JSON文字列に変換されない例

JSON文字列をオブジェクトに変換
リンクをコピーしました

JSON文字列をJavaScriptのオブジェクトに変換するには、以下のようにJSON.parse()メソッド使います。

コンソール | JSON文字列からオブジェクトへ変換
1
2
 // 引数に渡した文字列をJSONとして解析し、オブジェクトに変換する
JSON.parse(JSON文字列);

例えば、JSON文字列の箇所を以下のように記述します。

コンソール | parseメソッドにJSON文字列を記述する
1
JSON.parse('{"id":1,"name":"Tanaka","age":19}');

コンソールで実行すると、JSON.parseメソッドの引数に渡したJSON文字列がオブジェクトに変換されます。

parseメソッドにシングルクォーテーションで囲った例

引数の注意点
リンクをコピーしました

JSONは、ダブルクォーテーションを容認してしまうので、JSON.parse()メソッドの引数に渡す外側の引用符は、シングルクォテーション ではなく、ダブルクォテーションにするとエラーが発生します。

以下のように、先ほどのコードを外側の引用符をシングルクォテーションからダブルクォテーションに変更します。

シングルクォテーションからダブルクォーテーションに変更

コンソールで実行すると、以下のようにエラーが発生します。

JSON文字列をオブジェクトにパースしてエラーになる例

JSON.parseメソッドを使用する際は、引数に渡す外側の引用符をシングルクォテーションにするように注意してください。

オブジェクトに変換したデータの取り出し方
リンクをコピーしました

JSON.parseメソッドでオブジェクトに変換したJSON文字列のデータを取り出すには、以下のように記述します。

コンソール | オブジェクトに変換したデータを取り出す
1
2
3
4
5
6
7
8
9
10
const obj = JSON.parse('{"id":1,"name":"Tanaka","age":19}');

obj.id // obj["id"] でも良い
> 1

obj.name // obj["name"] でも良い
>"Tanaka"

obj.age // obj["age"] でも良い
>19

ネストした階層の場合
リンクをコピーしました

JSON文字列のデータが以下のようなネストした階層だった場合の取得方法も確認します。

ネストした階層のJSONデータ

ネストした階層のcompanyprivateのバリューを取得するには、以下のように親のキー名(email)に加えて、子のキー名(privatecompany)を指定してます。

コンソール | ネストした階層のデータを取得する
1
2
3
4
5
6
7
8
9
10
11
// JSON文字列をオブジェクトに変換してobjに格納する
const obj = JSON.parse('{"id": 1,"name": "Tanaka","age": 19, "email": {"company": "example.com","private": "pri-example.com"}}');
> {id: 1, name: "Tanaka", age: 19, email: {}}

// companyのバリューを取得
obj.email.company
> "example.com"

// privateのバリューを取得
obj.email.private
>"pri-example.com"

配列のネストした階層のデータを取得したい場合
リンクをコピーしました

以下のように、配列の中でネストした階層のデータを取得したい場合を確認していきます。

配列の中のオブジェクトがさらにネストしている例

上記の構造は、良くデータを外部のアプリケーションなどから取得(Web API)した際に、このような構造で返却される事が多いです。(実際は、もっと複雑です。)

配列の中のネストした階層のcompanyprivateのバリューを取得するには、以下のように記述します。

JSON | 配列の中でネストした階層のデータ
1
2
3
4
5
6
7
8
9
10
const obj = JSON.parse('{"users":[{"id":1,"nickname":"ピカ子","age":18,"email": {"company": "example1.com","private": "pri-example1.com"}},{"id":2,"nickname":"ピカオ","age":14,"email": {"company": "example2.com","private": "pri-example2.com"}}]}');
> {users: Array(2)}

// companyのバリューを取得
obj.users[0].email.company
> "example1.com"

// privateのバリューを取得
obj.users[0].email.private
> "pri-example1.com"

配列からデータを取り出してから、emailのネストしたキー名をそれぞれ指定する事でデータを取得する事が出来ます。

まとめ
  • JSON とは、JavaScript Object Notationの略でJavaScriptのオブジェクトの表記法をベースにしたデータフォーマットのこと
  • キー名は、必ずダブルクォーテーションをつける
  • JSON.parse()メソッドでJSON文字列をJavaScriptのオブジェクトに変換出来て、JSON.stringify()メソッドでJavaScriptのオブジェクトをJSON文字列に変換する事が出来る