1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

JSON.stringifyのreplacerはtoJSON()の後で呼ばれる

Posted at

JSON.stringify の第2引数はたいてい null を指定するけど、値を置換できる replacer 関数を指定することができる。
オブジェクトに toJSON() メソッドが生えていれば、それでも置換できる。
replacertoJSON の両方を使用していた場合は、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
ECMA2.png

(参考)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;
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?