Q1JSON.stringify(order, null, 2) のように字下げして変換したとき、返るものの typeof は何ですか?
JSON — stringify と parse
オブジェクトを文字列にして保存や送信ができる形にする JSON.stringify と、文字列からオブジェクトに戻す JSON.parse を扱います。字下げ付きの出力、壊れた文字列で起きるエラー、往復で失われる値まで進みます。
設定やカートの内容をブラウザに保存したり、サーバーへ送ったりするとき、オブジェクトのままでは渡せません。保存も通信も扱えるのは文字列だからです。
JSON(キーと値の組を文字列で表すためのデータ形式)に変換すれば、そのまま保存でき、受け取った側は元のオブジェクトに戻せます。この記事では、変換する JSON.stringify と、戻す JSON.parse を扱います。
オブジェクトを文字列にする — JSON.stringify
オブジェクトを保存や送信に使うには、いったん文字列にする必要があります。自分で "{" + キー + ":" + 値 + "}" のように文字列を継ぎ足して組み立てると、値に引用符が含まれたときに壊れるので、決まった形式に変換する関数を使います。
JSON.stringify(settings) と書くと、オブジェクトを JSON の書き方に沿った 1 行の文字列に変換します。返るのは文字列なので、typeof は "string" で、length や includes といった文字列のメソッドがそのまま使えます。
JSON は JavaScript の書き方とよく似ていますが、同じではありません。キーは必ず二重引用符で囲み、文字列の値も二重引用符だけを使います。
末尾のカンマは書けず、コメントも入れられません。この違いが、あとで扱う SyntaxError の原因です。
const product = { name: "ドリップコーヒー", price: 780, inStock: true };
const productJson = JSON.stringify(product);
console.log(productJson);
// {"name":"ドリップコーヒー","price":780,"inStock":true}
// 返るのは文字列なので、文字列のメソッドがそのまま使える
console.log(typeof productJson); // string
console.log(productJson.includes("price")); // true
// 配列も同じように変換できる
console.log(JSON.stringify(["キッチン", "文具"])); // ["キッチン","文具"]
読める形に整える — 3 つ目の引数で字下げする
1 行にまとまった JSON は通信には向きますが、中身を目で確かめたいときは読みづらくなります。設定ファイルとして書き出す場合や、動作を確認しながら開発する場面では、改行と字下げが入っている形が扱いやすくなります。
JSON.stringify(order, null, 2) のように 3 つ目の引数へ数値を渡すと、その数だけ半角スペースで字下げした複数行の文字列が返ります。2 つ目の引数は取り出すキーを選ぶためのもので、全部そのまま出すときは null を渡します。
整形しても返るものは文字列なので、split("\n") で行に分けられます。"\n" は改行 1 文字を表す書き方です。
const product = { name: "ドリップコーヒー", price: 780 };
// 第 3 引数に 2 を渡すと 2 スペースで字下げされる
const pretty = JSON.stringify(product, null, 2);
console.log(pretty);
// {
// "name": "ドリップコーヒー",
// "price": 780
// }
// 整形しても返るのは文字列
console.log(typeof pretty); // string
console.log(pretty.split("\n").length); // 4
文字列からオブジェクトに戻す — JSON.parse
保存しておいた文字列や、サーバーから受け取った文字列は、そのままでは order.total のように読めません。値を取り出したり計算したりするには、オブジェクトに戻す必要があります。
JSON.parse(savedJson) と書くと、JSON の文字列を読み取ってオブジェクトを作って返します。数値は数値、真偽値は真偽値として戻るので、order.total + 1000 のような計算がそのままできます。
配列も配列として戻り、length で件数を数えられます。
JSON の書き方に沿っていない文字列を渡すと SyntaxError が発生して、その行で実行が止まります。末尾に余分なカンマがある、キーが引用符で囲まれていない、途中で切れているといった場合です。
stringify で文字列にし、parse で戻します。JSON の書き方から外れていると SyntaxError で止まります。const savedJson = '{"name":"ドリップコーヒー","price":780,"tags":["キッチン"]}';
const product = JSON.parse(savedJson);
console.log(product.name); // ドリップコーヒー
// 数値は数値として戻るので、そのまま計算できる
console.log(product.price * 2); // 1560
// 配列は配列として戻る
console.log(product.tags.length); // 1
console.log(typeof product); // object
// 往復させると元と同じ中身に戻る
console.log(JSON.stringify(product) === savedJson); // true
受け取った文字列が壊れていることがある
通信が途中で切れたり、手で編集した設定ファイルに余分なカンマが残っていたりすると、JSON.parse は SyntaxError を発生させてその行で止まります。止まると後続の処理はまったく動かないため、外部から受け取った文字列を戻すときは、失敗する可能性を前提にします。
失敗しても処理を続ける書き方は、例外処理の記事で扱います。
往復で失われるもの — undefined と Date
JSON が表せるのは文字列・数値・真偽値・null・配列・オブジェクトだけです。それ以外の値を持つオブジェクトを変換すると、黙って消えたり別の形に置き換わったりします。
保存して読み直したら項目が減っていた、という食い違いはここで起きます。
値が undefined のプロパティは、変換の時点でキーごと消えます。関数を値に持つプロパティも同じく消えます。配列の中に undefined があるときは、位置を保つために null に置き換わります。
Date(日時を表す組み込みの値。本講座では扱いません)は文字列に変換されます。JSON.parse で戻したときも文字列のままで、日付として扱える形には戻りません。
戻したあとに日付として使いたいときは、自分で new Date(文字列) を書いて作り直します。
| 元の値 | JSON にすると | 戻したとき |
|---|---|---|
| 文字列・数値・真偽値・null | そのまま書き出される | 同じ型で戻る |
| undefined のプロパティ | キーごと消える | キーが無い |
| 関数を値に持つプロパティ | キーごと消える | キーが無い |
| 配列の中の undefined | null に置き換わる | null |
| Date | 文字列として書き出される | 文字列のまま |
const record = {
orderId: "ORD-1477",
couponCode: undefined,
orderedAt: new Date("2026-09-02T09:00:00Z"),
tags: ["キッチン", undefined],
};
const json = JSON.stringify(record);
console.log(json);
// {"orderId":"ORD-1477","orderedAt":"2026-09-02T09:00:00.000Z","tags":["キッチン",null]}
const restored = JSON.parse(json);
console.log("couponCode" in restored); // false(キーごと消えた)
console.log(typeof restored.orderedAt); // string(Date には戻らない)
console.log(restored.tags[1]); // null(配列の中は null になった)
理解度チェック
まずは1問ずつ答えてみましょう。
Q2JSON.parse('{"total":7400,}') を実行するとどうなりますか?
Q3値が undefined のプロパティを持つオブジェクトを JSON.stringify すると、そのプロパティはどうなりますか?