生の JSON オブジェクトは、あらゆる種類のプリミティブのような、不変で原子的なデータ構造と見なすことができます。これは通常のオブジェクトではなく、生の JSON テキスト以外のデータは持ちません。様々な理由で JSON.stringify 自身が生成できない形式にデータを「事前シリアライズ」するために使用します。最も典型的な使用する用途は、浮動小数点数の精度損失の問題です。例えば、次のような場合です。
js
JSON.stringify({ value: 12345678901234567890 });
// {"value":12345678901234567000}
この値は元の数値と正確には等しくありません!これは JavaScript がすべての数値に浮動小数点数を使用しているため、すべての整数を正確に表すことができないからです。数値リテラル 12345678901234567890 自体は、 JavaScript によって解釈されるときに、最も近い表現可能な数値に丸められます。
JSON.rawJSON がなければ、対応する JavaScript の数値が存在しないため、 JSON.stringify に 12345678901234567890 という数値リテラルを生成するように指示する方法はありません。生の JSON では、具体的な値を文字列化するように JSON.stringify() に直接指示することができます。
js
const rawJSON = JSON.rawJSON("12345678901234567890");
JSON.stringify({ value: rawJSON });
// {"value":12345678901234567890}
この例については、損失のない数値のシリアライズを参照してください。
JSON.rawJSON() に文字列を渡しましたが、最終的な JSON では数値になることに注意してください。これは、文字列が JSON のテキストをそのまま表しているからです。文字列をシリアライズしたい場合は、 JSON.rawJSON() に引用符で囲まれた文字列値を使用してください。
js
const rawJSON = JSON.rawJSON('"Hello world"');
JSON.stringify({ value: rawJSON });
// {"value":"Hello world"}
JSON.rawJSON は任意の JSON テキストを挿入することができますが、不正な JSON を作成することはできません。 JSON 構文で許可されていない何らかのものは、 JSON.rawJSON() でも許可されません。
js
const rawJSON = JSON.rawJSON('"Hello\nworld"'); // 改行は JSON 文字列で許可されていないので Syntax error
さらに、 JSON オブジェクトや配列を作成するのに JSON.rawJSON() を使用することはできません。
js
const numJSON = JSON.rawJSON("123");
const strJSON = JSON.rawJSON('"Hello world"');
const boolJSON = JSON.rawJSON("true");
const nullJSON = JSON.rawJSON("null");
console.log(
JSON.stringify({
age: numJSON,
message: strJSON,
isActive: boolJSON,
nothing: nullJSON,
}),
);
// {"age":123,"message":"Hello world","isActive":true,"nothing":null}
ただし、 JSON.rawJSON() を使用して JSON オブジェクトや配列を作成することはできません。
js
const arrJSON = JSON.rawJSON("[1, 2, 3]");
const objJSON = JSON.rawJSON('{"a": 1, "b": 2}');
// SyntaxError
数値の他に、 JavaScript の値と JSON のテキストが一対一に対応しない型は、文字列しかありません。文字列が JSON にシリアライズされるとき、 JSON 文字列リテラル内で合法でないもの(改行など)以外のすべてのコードポイントは、文字通りに出力されます。
js
console.log(JSON.stringify({ value: "\ud83d\ude04" })); // {"value":"😄"}
これは確実ではないかもしれません。この文字列の受信側では異なる形で Unicode を処理する可能性があるためです。相互運用性を向上させるために、エスケープシーケンスでシリアライズする文字列を明示的に指定することができます。
js
const rawJSON = JSON.rawJSON('"\\ud83d\\ude04"');
const objStr = JSON.stringify({ value: rawJSON });
console.log(objStr); // {"value":"\ud83d\ude04"}
console.log(JSON.parse(objStr).value); // 😄
rawJSON の二重バックスラッシュは、実際には単一のバックスラッシュ文字を表します。