reviver / replacer 関数の活用
JSON.parse() と JSON.stringify() には、変換処理をカスタマイズできる関数を渡すことができます。reviver と replacer を使いこなすと、Date の変換や特定プロパティの除外など、高度な JSON 処理が可能になります。
reviver 関数(JSON.parse の第2引数)
reviver 関数は、JSON.parse() の変換中に各キーと値のペアに対して呼び出されます。
const json = '{"name": "田中", "age": 25}';
const obj = JSON.parse(json, (key, value) => {
console.log(`${key}: ${value}`);
return value;
});
// 出力:
// name: 田中
// age: 25
// : [object Object] ← 最後にルートオブジェクトDate オブジェクトの復元
JSON では Date は文字列になってしまいますが、reviver を使えば Date オブジェクトとして復元できます。
const json = '{"event": "会議", "date": "2024-03-15T10:00:00.000Z"}';
const obj = JSON.parse(json, (key, value) => {
// ISO形式の日付文字列をDateに変換
if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}T/.test(value)) {
return new Date(value);
}
return value;
});
console.log(obj.date instanceof Date); // true
console.log(obj.date.getFullYear()); // 2024値の変換
reviver で値を変換することもできます。
const json = '{"price": "1500", "quantity": "3"}';
// 数値文字列を数値に変換
const obj = JSON.parse(json, (key, value) => {
if (typeof value === "string" && /^\d+$/.test(value)) {
return parseInt(value, 10);
}
return value;
});
console.log(typeof obj.price); // "number"replacer 関数(JSON.stringify の第2引数)
replacer 関数は、JSON.stringify() の変換中に各キーと値のペアに対して呼び出されます。undefined を返すと、そのプロパティは出力から除外されます。
const user = {
name: "田中",
password: "secret123",
email: "tanaka@example.com"
};
// パスワードを除外
const json = JSON.stringify(user, (key, value) => {
if (key === "password") {
return undefined;
}
return value;
});
console.log(json);
// '{"name":"田中","email":"tanaka@example.com"}'reviver(parse)
パース時に値を変換・復元する
replacer(stringify)
文字列化時に値を変換・除外する
配列による replacer
replacer には配列を渡すこともでき、その場合は指定したキーのみが出力されます。
const user = {
id: 1,
name: "田中",
email: "tanaka@example.com",
password: "secret",
createdAt: "2024-01-01"
};
// 指定したキーのみ出力
const json = JSON.stringify(user, ["id", "name", "email"]);
console.log(json);
// '{"id":1,"name":"田中","email":"tanaka@example.com"}'センシティブデータのマスキング
ログ出力時にパスワードなどをマスキングする例です。
function safeStringify(obj) {
const sensitiveKeys = ["password", "token", "secret", "apiKey"];
return JSON.stringify(obj, (key, value) => {
if (sensitiveKeys.includes(key)) {
return "***REDACTED***";
}
return value;
}, 2);
}
const config = {
url: "https://api.example.com",
apiKey: "sk-1234567890",
password: "secret123"
};
console.log(safeStringify(config));カスタム型の変換
独自クラスのインスタンスを JSON に変換し、復元する例です。
class User {
constructor(name, age) {
this.name = name;
this.age = age;
this._type = "User";
}
greet() {
return `Hello, ${this.name}!`;
}
}
// stringify 時にメタ情報を保持
const json = JSON.stringify(new User("田中", 25));
// parse 時に復元
const obj = JSON.parse(json, (key, value) => {
if (value && value._type === "User") {
return new User(value.name, value.age);
}
return value;
});
console.log(obj instanceof User); // true
console.log(obj.greet()); // "Hello, 田中!"reviver と replacer を活用することで、JSON の標準機能を超えた柔軟なデータ変換が実現できます。