JSON.stringify()
メソッドは JavaScript の値を JSON 文字列に変換します。置き換え関数を指定して値を置き換えたり、置き換え配列を指定して指定されたプロパティのみを含むようにしたりできます。
構文
JSON.stringify(value[, replacer[, space]])
引数
value
- JSON 文字列に変換する値。
replacer
Optional- 文字列化の手順の挙動を置き換える関数、または
String
とNumber
オブジェクトの配列であって、値のオブジェクトを JSON 文字列に含めるプロパティを選択するホワイトリストとして機能するもの。もしこの値が null であるか提供されない場合は、オブジェクトのすべてのプロパティが結果の文字列に含まれます。 space
Optional- 出力する JSON 文字列に可読性を目的に空白を挿入するために使う
String
またはNumber
オブジェクト。これがNumber
のときは空白として使う空白文字の数を示します。この数字は上限が 10 に設定されていて 10 より大きい場合 10 となります。1 より小さい値は空白を使わないことを示します。これがString
のときはその文字列(10 文字より長い場合はその最初の 10 文字)が空白として使われます。もしこの引数が提供されない(または null である)場合は、空白は使用されません。
説明
JSON.stringify()
は値をそれを表す JSON 表記に変換します:
- 配列でないオブジェクトのプロパティは、特定の順序で文字列化されることを保証されてはいません。文字列化において同じオブジェクトのプロパティの順序付けを信用しないでください。
Boolean
、Number
とString
オブジェクトは文字列化の際に対応するプリミティブな値に変換され、慣習的な変換セマンティクスと一致します。- もし変換の際に
undefined
、関数、またはシンボルに出会った場合、それは省略される(オブジェクトで見つかった時)かnull
に変更される(配列で見つかった時)ことになります。またJSON.stringify
はJSON.stringify(function(){})
やJSON.stringify(undefined)
のように「純粋」な値を渡した場合にundefined
を返すことがあります。 - プロパティのキーがシンボルであるプロパティはすべて、
replacer
関数を使用する場合でも完全に無視されます。 - enumerable でないプロパティは無視されます。
JSON.stringify({}); // '{}' JSON.stringify(true); // 'true' JSON.stringify('foo'); // '"foo"' JSON.stringify([1, 'false', false]); // '[1,"false",false]' JSON.stringify({ x: 5 }); // '{"x":5}' JSON.stringify(new Date(2006, 0, 2, 15, 4, 5)); // '"2006-01-02T15:04:05.000Z"' JSON.stringify({ x: 5, y: 6 }); // '{"x":5,"y":6}' または '{"y":6,"x":5}' JSON.stringify([new Number(1), new String('false'), new Boolean(false)]); // '[1,"false",false]' JSON.stringify({ x: [10, undefined, function(){}, Symbol('')] }); // '{"x":[10,null,null,null]}' // シンボル: JSON.stringify({ x: undefined, y: Object, z: Symbol('') }); // '{}' JSON.stringify({ [Symbol('foo')]: 'foo' }); // '{}' JSON.stringify({ [Symbol.for('foo')]: 'foo' }, [Symbol.for('foo')]); // '{}' JSON.stringify({ [Symbol.for('foo')]: 'foo' }, function(k, v) { if (typeof k === 'symbol') { return 'a symbol'; } }); // '{}' // enumerable でないプロパティ: JSON.stringify( Object.create(null, { x: { value: 'x', enumerable: false }, y: { value: 'y', enumerable: true } }) ); // '{"y":"y"}'
replacer
引数
replacer
引数は関数または配列です。関数については、キーと文字列化される値の 2 つの引数を取ります。キーをもつオブジェクトが replacer
の this
パラメータとして提供されます。最初に文字列化されるオブジェクトを表す空のキーで呼ばれ、それからそれぞれの文字列化されるオブジェクトや配列のプロパティについて呼ばれます。JSON 文字列に加える値を、次のように返すべきです:
Number
を返した場合、その数値に対応する文字列が JSON 文字列に追加される時にそのプロパティの値として使用されます。String
を返した場合、その文字列が JSON 文字列に追加される時にそのプロパティの値として使用されます。Boolean
を返した場合、"true" または "false" が適切に JSON 文字列に追加される時にそのプロパティの値として使用されます。- その他のオブジェクトを返した場合、そのオブジェクトは再帰的に JSON 文字列に文字列化されます。その時それぞれのプロパティに対して、そのオブジェクトが関数である場合を除いて
replacer
関数を呼びます。関数である場合は JSON 文字列には何も追加されません。 undefined
を返した場合、そのプロパティは出力する JSON 文字列には含まれません。
replacer
関数を配列から値を取り除くために使うことはできません。undefined
または関数を返した場合は代わりに null
が使われます。関数を使った例
function replacer(key, value) { if (typeof value === "string") { return undefined; } return value; } var foo = {foundation: "Mozilla", model: "box", week: 45, transport: "car", month: 7}; var jsonString = JSON.stringify(foo, replacer);
結果の JSON 文字列は {"week":45,"month":7}
です。
配列を使った例
replacer
が配列である場合、その配列の値は結果の JSON 文字列に含めるプロパティの名前を示します。
JSON.stringify(foo, ['week', 'month']); // '{"week":45,"month":7}', "week" と "month" プロパティだけが保持される
space
引数
space
引数は最終的な文字列でのスペーシングを調整するために用いることができます。もし数値であれば、文字列化での連続するレベルはそれぞれその量(10 まで)の空白文字でインデントされます。もし文字列であれば、連続するレベルはこの文字列(またはその最初の 10 文字)でインデントされます。
JSON.stringify({ a: 2 }, null, ' '); // '{ // "a": 2 // }'
タブ文字を使って標準的な整形の見た目を真似します:
JSON.stringify({ uno: 1, dos: 2 }, null, '\t'); // 返る文字列: // '{ // "uno": 1, // "dos": 2 // }'
toJSON()
の挙動
もし文字列化されるオブジェクトが toJSON
という名前で値が関数のプロパティを持っていた場合、toJSON()
メソッドは JSON 文字列化の挙動をカスタマイズします: そのシリアライズされるオブジェクトの代わりに、toJSON()
メソッドが返した値がシリアライズされます。例えば:
var obj = { foo: 'foo', toJSON: function() { return 'bar'; } }; JSON.stringify(obj); // '"bar"' JSON.stringify({ x: obj }); // '{"x":"bar"}'
JavaScript としての使用に際してのそのままの JSON.stringify
の問題
JSON は JavaScript の完全に厳密なサブセットではないことに注意してください。2 つの行末文字(Line separator と Paragraph separator)は JSON ではエスケープする必要はありませんが JavaScript ではエスケープする必要があります。ゆえに、もし JSON が評価されるまたは JSONP で直接使われることになっている場合は、次のユーティリティが使えます:
function jsFriendlyJSONStringify (s) { return JSON.stringify(s). replace(/\u2028/g, '\\u2028'). replace(/\u2029/g, '\\u2029'); } var s = { a: String.fromCharCode(0x2028), b: String.fromCharCode(0x2029) }; try { eval('(' + JSON.stringify(s) + ')'); } catch (e) { console.log(e); // "SyntaxError: unterminated string literal" } // catch する必要はない eval('(' + jsFriendlyJSONStringify(s) + ')'); // Firefox での console.log はコンソールにログをする場合 // Unicode エスケープを解除するので、alert を使う alert(jsFriendlyJSONStringify(s)); // {"a":"\u2028","b":"\u2029"}
localStorage
で JSON.stringify()
を使う例
ユーザ側で作成したオブジェクトを保持して、ブラウザが閉じられた後も復元できるようにしたい場合に、JSON.stringify()
が適用できる模範的な例:
関数は有効な JSON のデータ型ではないため、うまくいきません。しかしながらまず toString メソッドを通じて文字列に(例えば replacer の中で)変換すれば表示することができます。また Date
のような一部のオブジェクトは JSON.parse()
のあと文字列になるでしょう。
// JSON の一例を作成 var session = { 'screens': [], 'state': true }; session.screens.push({ 'name': 'screenA', 'width': 450, 'height': 250 }); session.screens.push({ 'name': 'screenB', 'width': 650, 'height': 350 }); session.screens.push({ 'name': 'screenC', 'width': 750, 'height': 120 }); session.screens.push({ 'name': 'screenD', 'width': 250, 'height': 60 }); session.screens.push({ 'name': 'screenE', 'width': 390, 'height': 120 }); session.screens.push({ 'name': 'screenF', 'width': 1240, 'height': 650 }); // JSON.stringify() で JSON 文字列に変換してから // session の名前で localStorage に保存 localStorage.setItem('session', JSON.stringify(session)); // JSON.stringify() で生成されて localStorage に保存された文字列を // 再び JSON オブジェクトに変換する方法の例 var restoredSession = JSON.parse(localStorage.getItem('session')); // ここで変数 restoredSession には localStorage に保存されていた // オブジェクトが入っている console.log(restoredSession);
仕様
仕様書 | 策定状況 | コメント |
---|---|---|
ECMAScript 5.1 (ECMA-262) JSON.stringify の定義 |
標準 | 最初期の定義。JavaScript 1.7 で実装されました。 |
ECMAScript 2015 (6th Edition, ECMA-262) JSON.stringify の定義 |
標準 | |
ECMAScript 2017 Draft (ECMA-262) JSON.stringify の定義 |
ドラフト |
ブラウザ実装状況
機能 | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
基本サポート | (有) | 3.5 (1.9.1) | 8.0 | 10.5 | 4.0 |
機能 | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
基本サポート | (有) | (有) | 1.0 (1.0) | (有) | (有) | (有) |