JSON.stringify
の第2引数はたいてい null
を指定するけど、値を置換できる replacer
関数を指定することができる。
オブジェクトに toJSON()
メソッドが生えていれば、それでも置換できる。
replacer
と toJSON
の両方を使用していた場合は、toJSON
が先に実行される。
だから、toJSON
実装済クラスのインスタンスを外から replacer
で変換することは難しい。
検証用コード:
class Foo {
toJSON() {
console.log("Foo#toJSON() called");
return "FOO";
}
}
const data = {foo: new Foo()};
JSON.stringify(data, (key, value) => {
console.log(`replacer(${JSON.stringify(key)}) called`);
return value;
});
実行結果は以下。
replacer("") called
Foo#toJSON() called
replacer("foo") called
1行目は親オブジェクトの replacer
、2行目は toJSON
、3行目は Foo の replacer
。
ECMAScript の仕様書にも toJSON
が先で ReplacerFunction
が後と定義されてる。
https://262.ecma-international.org/#sec-serializejsonproperty
(参考)TypeScript の replacer
の定義:
https://github.com/microsoft/TypeScript/blob/main/lib/lib.es5.d.ts#L1052
/**
* Converts a JavaScript value to a JavaScript Object Notation (JSON) string.
* @param value A JavaScript value, usually an object or array, to be converted.
* @param replacer A function that transforms the results.
* @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.
*/
stringify(value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string;