6時だョ!!全員集合!!

Rails・JavaScrictを中心にアウトプットします。

2022年3月15日 JSON (JavaScript Primer)JSONにシリアライズできないオブジェクト

JSONシリアライズできないオブジェクト

JSON.stringifyメソッドはJSONで表現可能な値だけをシリアライズします。

(※シリアライズとは、複数の要素を一列に並べる操作や処理のこと。)

JSONに変換可能な値として紹介されている、文字列、数値、真偽値、配列、オブジェクトを出力しました。

console.log(JSON.stringify({ x: "yano" }));
console.log(JSON.stringify({ x: 10  }));
console.log(JSON.stringify({ x: true })); 
console.log(JSON.stringify({ x: ["yano", 11] })); 
console.log(JSON.stringify({ x: { reizouko: "touhu" } }));

▶{"x":"yano"}
▶{"x":10}
▶{"x":true}
▶{"x":["yano",11]}
▶{"x":{"reizouko":"touhu"}}


シリアライズ前の値 シリアライズ後の値
文字列・数値・真偽値 対応する値
null null
配列 配列
オブジェクト オブジェクト
関数 変換されない(配列のときはnull)
undefined 変換されない(配列のときはnull)
Symbol 変換されない(配列のときはnull)
RegExp {}
Map,Set {}


// 値が関数のプロパティ
console.log(JSON.stringify({ x: function() {} })); // => '{}'
// 値がSymbolのプロパティ
console.log(JSON.stringify({ x: Symbol("") })); // => '{}'
// 値がundefinedのプロパティ
console.log(JSON.stringify({ x: undefined })); // => '{}'
// 配列の場合
console.log(JSON.stringify({ x: [10, function() {}] })); // => '{"x":[10,null]}'
// キーがSymbolのプロパティ
JSON.stringify({ [Symbol("foo")]: "foo" }); // => '{}'
// 値がRegExpのプロパティ
console.log(JSON.stringify({ x: /foo/ })); // => '{"x":{}}'
// 値がMapのプロパティ
const map = new Map();
map.set("foo", "foo");
console.log(JSON.stringify({ x: map })); // => '{"x":{}}'
  • 配列の中にJSONに変換できないものが入っていたらnull になります。
  • 正規表現とMap,Setは列挙可能なプロパティを持たないため{} に変換されます。

JSON.stringifyメソッドがシリアライズに失敗する場合もあります

良くある例として循環参照しているオブジェクトに対してシリアライズしようとしたときに例外が投げられるケースです。 例のように、あるオブジェクトのプロパティを再帰的にたどって自分自身が見つかるような場合はシリアライズが不可能となります。

const obj = { foo: "foo" };
obj.self = obj;
try {
    JSON.stringify(obj);
} catch (error) {
    console.error(error); // => "TypeError: Converting circular structure to JSON"
}

このようなときのために例外処理をしておきましょう。

toJSONメソッドを使ったシリアライズ

オブジェクトがtoJSONメソッドを持っている場合、JSON.stringifyメソッドは既定の文字列変換ではなくtoJSONメソッドの返り値を使います。

引数に直接渡さなくてもプロパティとしてtoJSONがある場合もtoJSONが返り値になります。

const obj = {
    foo: "foo",
    toJSON() {
        return "bar";
    }
};
console.log(obj); // => { foo: 'foo', toJSON: [Function: toJSON] }
console.log(JSON.stringify(obj)); // => '"bar"'
console.log(JSON.stringify({ x: obj })); // => '{"x":"bar"}'

toJSONメソッドは自作のクラスを特殊な形式でシリアライズする目的などに使われます。

この章のまとめ

この章では、JSONについて学びました。

参考

JSONにシリアライズできないオブジェクト (JavaScript Primer)