こんにちは、かつコーチです。
前回は「外部APIからデータを取得して表示する」で、実際に一覧データをAPIから取得して画面に表示する流れを扱いました。
その中で何度も登場した .json() というメソッドや、{ } で囲まれたデータの形。
今回は、これらの正体であるJSONについてじっくり解説していきます。
JSONとは?
正式名称と読み方
JSONは「JavaScript Object Notation」の略で、読み方は「ジェイソン」です。
名前に「JavaScript」と付いていますが、今ではJavaScriptに限らず、PHPやPython、Javaなど多くのプログラミング言語で共通して使われるデータのやり取りのための形式になっています。
「異なるプログラム同士が、データをやり取りするための共通言語」のようなものだとイメージしてください。
なぜJSONが使われるのか
APIを通じてサーバーとブラウザがデータをやり取りするとき、お互いが理解できる「共通のルール」が必要です。
JSONは次のような理由から、その共通ルールとして広く採用されています。
- 人間が見てもある程度読みやすい形式である
- JavaScriptのオブジェクトの書き方とよく似ていて扱いやすい
- ほとんどのプログラミング言語で標準的にサポートされている
前回までの記事でfetchを使ってAPIからデータを取得したとき、返ってきたデータの中身がまさにこのJSON形式でした。
JSONの基本的な書き方
JSONのデータ構造
JSONは、次のようなルールでデータを表現します。
{
"name": "かつコーチ",
"age": 30,
"isActive": true,
"skills": ["JavaScript", "PHP"],
"address": {
"city": "東京"
}
}
主なルールは次の通りです。
- データ全体を
{ }(波括弧)で囲む - 「キー」と「値」を
:(コロン)でつなぐ - キーは必ずダブルクォートで囲む
- 複数のデータは
,(カンマ)で区切る - 値には文字列・数値・真偽値・配列・別のオブジェクトを入れられる
見た目はJavaScriptのオブジェクトとよく似ていますが、JSONには独自の細かいルールがあります。
JavaScriptのオブジェクトとの違い
初心者がよく混同しがちなのが、JavaScriptのオブジェクトとJSONの違いです。
| JavaScriptのオブジェクト | JSON | |
|---|---|---|
| キーのクォート | 省略可能 | 必ずダブルクォートが必要 |
| 値に関数を入れる | 可能 | 不可 |
| シングルクォート | 使える | 使えない(ダブルクォートのみ) |
| 用途 | プログラム内でのデータの入れ物 | データをやり取りするための「文字列」形式 |
一番の違いは、JSONはあくまで「文字列」であるという点です。
見た目はオブジェクトに似ていますが、実際にはただのテキストデータであり、そのままではJavaScriptのプログラムの中で . を使ってプロパティにアクセスすることはできません。
JSONとJavaScriptオブジェクトを変換する
JSON.parse():JSON文字列 → オブジェクトへ変換
サーバーから受け取ったJSON(文字列)を、JavaScriptで扱えるオブジェクトに変換するのが JSON.parse() です。
const jsonText = '{"name": "かつコーチ", "age": 30}';
const userObject = JSON.parse(jsonText);
console.log(userObject.name); // かつコーチ
console.log(typeof jsonText, typeof userObject); // string object
JSON.parse() を通すことで初めて、.name のようにプロパティへアクセスできるオブジェクトになります。
実は、前回までのfetchの中で使っていた response.json() は、この JSON.parse() を内部で自動的に行ってくれているメソッドです。
JSON.stringify():オブジェクト → JSON文字列へ変換
逆に、JavaScriptのオブジェクトをJSON文字列に変換するのが JSON.stringify() です。
const userObject = {
name: "かつコーチ",
age: 30
};
const jsonText = JSON.stringify(userObject);
console.log(jsonText); // {"name":"かつコーチ","age":30}
console.log(typeof jsonText); // string
サーバーに向けてデータを送信するとき(フォームの内容を送るときなど)は、この JSON.stringify() でオブジェクトを文字列に変換してから送る必要があります。
async function postUser() {
const newUser = { name: "かつコーチ", age: 30 };
const response = await fetch("https://jsonplaceholder.typicode.com/users", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(newUser) // オブジェクトを文字列に変換して送信する
});
const result = await response.json();
console.log(result);
}
postUser();
「受け取るときはparse」「送るときはstringify」という向きをセットで覚えておくと迷いにくくなります。
つまずきやすいポイント
JSON.parseに壊れた文字列を渡してエラーになる
私が実際につまずいたのが、JSON.parseに渡す文字列の形式ミスでした。
❌ Before:シングルクォートやキーのクォート抜けでエラーになる
const jsonText = "{name: 'かつコーチ', age: 30}"; // ダブルクォートになっていない
const userObject = JSON.parse(jsonText);
// SyntaxError: Unexpected token n in JSON at position 1
このコードは、キーの name にダブルクォートが付いておらず、値もシングルクォートになっているため、正しいJSON形式として認識されません。
私は当初、このエラーメッセージの「Unexpected token n」の「n」が何を指しているのか分からず、しばらく悩んでしまいました。
実際には、{ の次に来るべき " の代わりに n(nameの頭文字)が来ていたことが原因でした。
✅ After:JSONのルールに沿った文字列にする
const jsonText = '{"name": "かつコーチ", "age": 30}'; // キーも値もダブルクォート
const userObject = JSON.parse(jsonText);
console.log(userObject.name); // かつコーチ
JSON文字列を手で書くときは、キーは必ずダブルクォートで囲む、というルールを徹底することでこのエラーは防げます。
すでにオブジェクトになっているものをさらにparseしようとする
fetchを使っているとき特有のつまずきもあります。
❌ Before:response.json()の結果をさらにJSON.parseしてしまう
async function getUser() {
const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
const data = await response.json(); // すでにオブジェクトに変換済み
const parsedAgain = JSON.parse(data); // オブジェクトをparseしようとしてエラー
console.log(parsedAgain);
}
// TypeError: JSON.parse を実行するとエラーになる(data.toString() の結果が正しいJSON文字列でないため)
response.json() の時点ですでに JSON.parse() 相当の処理が完了しているため、その結果をさらに JSON.parse() に渡すのは誤りです。
✅ After:response.json()の結果はそのままオブジェクトとして使う
async function getUser() {
const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
const data = await response.json(); // ここですでにオブジェクトになっている
console.log(data.name); // そのままプロパティにアクセスできる
}
「今扱っているのが文字列なのか、それともすでにオブジェクトなのか」を意識する癖をつけると、こうした変換ミスは防ぎやすくなります。
迷ったときは typeof で確かめてみるのがおすすめです。
まとめ
この記事のポイント
- JSONはプログラミング言語をまたいで使われる、データをやり取りするための共通形式
- キーは必ずダブルクォートで囲むなど、JavaScriptのオブジェクトとは異なるルールがある
- 受け取るときは
JSON.parse()、送るときはJSON.stringify()で変換する response.json()はすでに変換済みのオブジェクトなので、重ねてparseしないよう注意する
次に読むべき記事
JSONの扱い方が分かったところで、次はAPI通信でつまずきやすい「エラー」への対処方法を学んでいきます。
→ 次の記事:非同期処理のエラーハンドリング(try-catch)