毎回ログ仕込むのが地味にめんどくさくなってきたのでUtilをつくろうと思いメモとして残しておく。
JSON.stringify()について
変換できるデータ型と結果
データ型 | 変換結果 |
オブジェクト | JSONオブジェクト |
配列 | JSON配列 |
文字列 | JSON文字列 |
数値 | JSON数値 |
true , false | true , false |
null | null |
undefined | 出力から除外される |
関数 | 出力から除外される |
シンボル | 出力から除外される |
replacer で出力内容をカスタマイズ
a. プロパティをフィルタリング
replacer
に配列を渡すと、指定したキーだけが出力されます。
1 2 3 4 |
const obj = { name: "Alice", age: 25, password: "secret" }; const jsonString = JSON.stringify(obj, ["name", "age"]); console.log(jsonString); // 出力: '{"name":"Alice","age":25}' |
b. 値を動的に変換
replacer
に関数を渡すと、値を動的に変更できます。
1 2 3 4 5 6 7 8 9 |
const obj = { name: "Alice", age: 25, password: "secret" }; const jsonString = JSON.stringify(obj, (key, value) => { if (key === "password") { return undefined; // password を削除 } return value; }); console.log(jsonString); // 出力: '{"name":"Alice","age":25}' |
循環参照への対処
オブジェクト内で循環参照がある場合、JSON.stringify
はエラーをスローします。
1 2 3 4 5 6 7 8 9 10 |
const obj = {}; obj.self = obj; // 循環参照 try { JSON.stringify(obj); } catch (e) { console.error("Error:", e.message); } // 出力: Error: Converting circular structure to JSON |
対処法: カスタム replacer
を作成して循環参照を防ぐ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
const seen = new WeakSet(); const obj = { name: "Alice" }; obj.self = obj; const jsonString = JSON.stringify(obj, (key, value) => { if (typeof value === "object" && value !== null) { if (seen.has(value)) { return "[Circular]"; } seen.add(value); } return value; }); console.log(jsonString); // 出力: '{"name":"Alice","self":"[Circular]"}' |
toJSON メソッドを利用
オブジェクトが toJSON
メソッドを持っている場合、JSON.stringify
はこのメソッドを優先します。
1 2 3 4 5 6 7 8 9 10 11 12 |
const obj = { name: "Alice", age: 25, toJSON() { return { name: this.name }; // age を除外 }, }; const jsonString = JSON.stringify(obj); console.log(jsonString); // 出力: '{"name":"Alice"}' |
注意点
シリアライズの制限
undefined、関数、シンボル はJSON文字列に含まれません。
配列内の undefined は null に変換されます。
1 2 3 4 |
const arr = [undefined, () => {}, Symbol("id")]; console.log(JSON.stringify(arr)); // 出力: '[null,null,null]' |
日付オブジェクト
Date
は ISO 8601 形式の文字列に変換されます。
1 2 3 4 |
const date = new Date(); console.log(JSON.stringify({ now: date })); // 出力: '{"now":"2024-12-04T12:34:56.789Z"}' |
Map や Set
Map
や Set
はシリアライズされません。必要に応じて変換が必要です。
1 2 3 4 |
const map = new Map([["key", "value"]]); console.log(JSON.stringify([...map])); // 出力: '[["key","value"]]' |
自作のカスタムログ関数を作成する
デフォルトの console.log
をオーバーライドして、色付きの出力を作成
1 2 3 4 5 6 7 8 9 10 11 |
const originalLog = console.log; // カスタムログ関数 console.log = (...args) => { const coloredLog = '\x1b[36m[MY LOG]\x1b[0m'; // ANSIエスケープコードで色付け originalLog(coloredLog, ...args); }; // 使用例 console.log("This is a test log!"); |
[MY LOG]
が表示され、色が変更されます(デバッグターミナルで動作)。ただし、React Native の Metro Bundler や iOS/Android のログビューア(adb logcat
など)では色付けが反映されないことがあり。
カラフルなログ
1 2 3 |
console.log('\x1b[32m%s\x1b[0m', '[LOG]', 'This is a green log'); console.log('\x1b[31m%s\x1b[0m', '[ERROR]', 'This is a red error log'); |
カラーコードについて
1. 標準的なANSIカラーコード(8色 + 明るい8色 = 16色)
基本8色
コード | 色名 | 説明 |
---|---|---|
\x1b[30m | 黒 | Black |
\x1b[31m | 赤 | Red |
\x1b[32m | 緑 | Green |
\x1b[33m | 黄色 | Yellow |
\x1b[34m | 青 | Blue |
\x1b[35m | マゼンタ | Magenta |
\x1b[36m | シアン | Cyan |
\x1b[37m | 白 | White |
明るいバージョン(Bright Colors)
コード | 色名 | 説明 |
---|---|---|
\x1b[90m | 明るい黒 | Bright Black (Gray) |
\x1b[91m | 明るい赤 | Bright Red |
\x1b[92m | 明るい緑 | Bright Green |
\x1b[93m | 明るい黄色 | Bright Yellow |
\x1b[94m | 明るい青 | Bright Blue |
\x1b[95m | 明るいマゼンタ | Bright Magenta |
\x1b[96m | 明るいシアン | Bright Cyan |
\x1b[97m | 明るい白 | Bright White |
- リセット:
\x1b[0m
(色設定を元に戻す)
1 2 3 |
console.log('\x1b[31mThis is red text\x1b[0m'); console.log('\x1b[32mThis is green text\x1b[0m'); |
2. 256色のANSIエスケープコード
- 形式:
\x1b[38;5;<n>m
(前景色)、\x1b[48;5;<n>m
(背景色) <n>
は0〜255の範囲で、次のように分類されます:- 0〜15: 標準色(基本8色 + 明るい8色)
- 16〜231: 6x6x6のRGBカラーパレット
- 232〜255: グレースケール(黒〜白)
1 2 3 |
console.log('\x1b[38;5;82mThis is bright green\x1b[0m'); console.log('\x1b[48;5;196mThis has a red background\x1b[0m'); |
3. 24ビットフルカラー(RGBカラー)
- 形式:
\x1b[38;2;<r>;<g>;<b>m
(前景色)、\x1b[48;2;<r>;<g>;<b>m
(背景色) <r>
、<g>
、<b>
はそれぞれ0〜255のRGB値。
1 2 3 4 |
console.log('\x1b[38;2;255;0;0mThis is pure red\x1b[0m'); console.log('\x1b[38;2;0;255;0mThis is pure green\x1b[0m'); console.log('\x1b[38;2;0;0;255mThis is pure blue\x1b[0m'); |
4. 使えるカラーコードの数
標準: 8色 + 明るい8色 = 16色
256色モード: 16色 + 拡張240色 = 256色
フルカラー: 24ビットのRGBで 16,777,216色
5. 注意点
ターミナル依存: ANSIカラーコードがサポートされるかどうかは、使っているターミナル(やツール)に依存します。
Metro Bundler や Node.js ターミナルでは基本的なANSIカラー(16色や256色)が利用可能。
AndroidやiOSのネイティブログビューアでは色付けが無効になることがあります。
React Native 開発では、主にターミナル出力で使えるANSIカラー(16色〜256色)が実用的です。
1 2 3 4 |
console.log('\x1b[31m[ERROR]\x1b[0m This is an error message'); console.log('\x1b[38;5;82m[INFO]\x1b[0m This is an informational message'); console.log('\x1b[38;2;0;128;255m[DEBUG]\x1b[0m This is a debug message'); |
コメント