JSON を変換する parse と stringify メソッドの使い方についてです。
JSON.parse
JSON.parse()
メソッドは JSON 文字列を解析して JavaScript のオブジェクトに変換します。
JSON.parse(text [, reviver])
基本的な変換は次の通りです。
JSON.parse('{}'); // {} -> [object Object] JSON.parse('{"bar": 1234, "foo": undefined}'); // {bar: 1234} -> [object Object] JSON.parse('"foo"'); // "foo" -> [object String] JSON.parse('true'); // true -> [object Boolean] JSON.parse('[1, 5, false]'); // [1, 5, false] -> [object Array] JSON.parse('null'); // null -> [object Null]
JSON.parse()
に渡す JSON 文字列は JSON 構文に準拠する必要があるため、次のようなパターンは SyntaxError が発生します。JSON 構文の詳細は コチラ などを参照してください。
- 文字列がダブルクオーテーションで括られていない。
- 真偽値(true / false)や null が大文字。
- オブジェクトのキーが文字列じゃない。
JSON.parse("hoge"); // 文字列がダブルクォーテーションで括られていない。 JSON.parse("'hoge'"); // 文字列がシングルクォーテーションで括られている。 JSON.parse('Null'); // 先頭が大文字なので文字列として認識されてエラーになる。 JSON.parse('True'); // 先頭が大文字なので文字列として認識されてエラーになる。 JSON.parse('"true"'); // エラーにはならないが String 型に変換される。 JSON.parse('{1234: true}'); // キーが文字列じゃない(ダブルクォーテーションで括られていない)
reviver
は省略可能ですが、関数を指定した場合はオブジェクトを返す前に各メンバーを変換する方法を指示します。
reviver の関数はオブジェクトの場合プロパティ名とプロパティの値を引数として呼びだされます。関数がundefined
やnull
を返した場合、そのプロパティは結果のオブジェクトから削除され、有効な値を返した場合はその戻り値としてプロパティが再定義されます。
JSON.parse('{"one": 1, "two": 2, "three": true}', function(key, value) { if (key === '') return value; if (Number.isFinite(value)) { return String(value * 2); // 数字の場合は2を掛けて文字列として出力 } else { return undefined; // 数字のみを返したい } }); // <- {one: "2", two: "4"}
また、関数は最終的に空の文字列であるプロパティ名と、変換後のオブジェクトの値で呼び出されます。この時に値をそのまま返すようにしないとJSON.parse()
自体の結果がundefined
となってしまいます。例えば上記のコードからif (key === '')
の行をコメントアウトすると結果が次のようにundefined
となります。
JSON.parse('{"one": 1, "two": 2, "three": true}', function(key, value) { //if (key === '') return value; console.log(value); if (Number.isFinite(value)) { return String(value * 2); } else { return undefined; // 最後の変換後オブジェクトもここに入る } }); // 1 // 2 // true // Object {one: "2", two: "4"} // <- undefined
配列の場合はインデックスと値を引数として呼び出されます。
JSON.parse('[1, 2, true]', function(i, value) { console.log(i + ":" + value); if (Number.isFinite(value)) { return String(value); } else { return value; // if (key === '') の判定が無くてもここでは値をそのまま返してるのでOK } }); // 0:1 // 1:2 // 2:true // :1,2,true // <- ["1", "2", true]
JSON.parse() - JavaScript | MDN
JSON.stringify
JSON.stringify()
メソッドは JavaScript の値を JSON 文字列に変換します。
JSON.stringify(value[, replacer[, space]])
基本的な変換は次の通りです。undefined
や関数、Symbol が存在した場合、オブジェクトの場合は削除され、配列の場合はnull
に置き換えられます。
JSON.stringify({}); // '{}' JSON.stringify({ x: 10, y: undefined, z: 20 }); // '{"x":10,"z":20}' JSON.stringify("foo"); // '"foo"' JSON.stringify(true); // 'true' JSON.stringify([1, "false", false, undefined]); // '[1,"false",false,null]' JSON.stringify(null); // 'null'
replacer
は省略可能です。関数を指定した場合は文字列を返す前にプロパティ値を変換します。
replacer の関数はオブジェクトの場合プロパティ名とプロパティの値を引数として呼びだされます。関数がundefined
を返した場合、そのプロパティは結果のオブジェクトから削除され、有効な値を返した場合はその戻り値としてプロパティが再定義されます。JSON.parse()
と同じようにルートオブジェクトのプロパティ名が空で呼ばれるので値をそのまま返さないといけません
JSON.stringify({"one": 1, "two": 2, "three": true}, function(key, value) { if (key === '') return value; if (Number.isFinite(value)) { return String(value * 2); // 数字の場合は2を掛けて文字列として出力 } else { return undefined; // 数字のみを返したい } }); // <- '{"one":"2","two":"4"}'
replacer に配列を指定した場合は配列にあるプロパティだけが保持されます。
JSON.stringify({"one": 1, "two": 2, "three": true}, ["two","three"]); // <- '{"two":2,"three":true}'
space
は省略可能です。指定した数値や文字列で結果を整形して出力します。
JSON.stringify({one: 1, two: 2}, null, 2); //"{ // "one": 1, // "two": 2 //}" JSON.stringify({one: 1, two: 2}, null, '\t'); //"{ // "one": 1, // "two": 2 //}"
JSON.stringify() - JavaScript | MDN
関連リンク
JSON in JavaScript
JSON - JavaScript | MDN
ネイティブ JSON を使う | MDN