Node.jsのconsole.logでネストが深くても[Object]を出さずに全てを表示する方法
バックエンドのAPIから取得したデータを確認したい場合などで、ネストが深いデータだと[Object]
のように途中から表示されないことがあります。
表示を省略させない方法がいくつかあると知ったのですが、それぞれにメリデメがあったので調べた結果をまとめています。
結論
console.dir(obj, { depth: null });
を使いましょう。
問題点を確認する
次のようなデータがあるとします。
const obj = {
key1: {
key2: {
key3: {
key4: {
key5: {
key6: 'value',
},
},
},
},
},
};
console.log(obj);
と記述すると次のような出力になります。
{ key1: { key2: { key3: [Object] } } }
3階層以降が[Object]
になって確認できなくなっています。
コンテンツに関するありそうなデータを作ってみました。
const contents = [
{
id: 1,
username: '山田太郎',
posts: [
{
id: 1,
title: '今日の手料理: 簡単!鮭の塩麹焼き',
content:
'久しぶりに自宅で本格的な料理を作りました。塩麹で下味をつけると、鮭がとても柔らかく仕上がりますよ。',
tags: ['料理', '和食', '簡単レシピ'],
likes: 42,
comments: 7,
createdAt: '2024-03-15T19:30:00',
},
{
id: 2,
title: '北海道旅行の思い出 - 札幌編',
content:
'先週末に札幌に行ってきました。雪まつり後の美しい街並みと、美味しいラーメンを堪能しました!',
tags: ['旅行', '北海道', '札幌'],
likes: 89,
comments: 15,
createdAt: '2024-03-22T14:45:00',
},
],
},
];
同じようにconsole.log()
で出力すると、感覚的に階層は深くなさそうなposts
内のオブジェクトが[Object], [Object]
になっています。
[ { id: 1, username: '山田太郎', posts: [ [Object], [Object] ] } ]
console.log('%o', obj);
を使用する
console.log()
の第一引数には文字列置換を指定できます。
いくつか用意されていますが%o
を指定すると、出力される階層が深くなります。
%o
JavaScript オブジェクトを「最適に有益な書式設定」スタイルで出力します。例えば、DOM 要素は要素インスペクターに現れるのと同じ方法で表示されます。
console.log('%o', obj);
と記述すると次のような出力になります。
%o
なしだと3階層までだったのが5階層まで出力できています。
{
key1: {
key2: { key3: { key4: { key5: [Object] } } }
}
}
コンテンツデータで試してみても、省略されていたposts
内のオブジェクトが出力できているのが確認できます。
[
{
id: 1,
username: '山田太郎',
posts: [
{
id: 1,
title: '今日の手料理: 簡単!鮭の塩麹焼き',
content: '久しぶりに自宅で本格的な料理を作りました。塩麹で下味をつけると、鮭がとても柔らかく仕上がりますよ。',
tags: [ '料理', '和食', '簡単レシピ', [length]: 3 ],
likes: 42,
comments: 7,
createdAt: '2024-03-15T19:30:00'
},
{
id: 2,
title: '北海道旅行の思い出 - 札幌編',
content: '先週末に札幌に行ってきました。雪まつり後の美しい街並みと、美味しいラーメンを堪能しました!',
tags: [ '旅行', '北海道', '札幌', [length]: 3 ],
likes: 89,
comments: 15,
createdAt: '2024-03-22T14:45:00'
},
[length]: 2
]
},
[length]: 1
]
console.log(JSON.stringify(obj, null, 2));
を使用する
オブジェクトをJSON文字列に変換するJSON.stringify()
を使うと、全てのデータを出力できます。ディープコピーをする場合にも使うことがあるのでイメージしやすいですね。
JSON.stringify()
の第三引数であるspace
に数値を指定するとインデントが付けられるようになります。
console.log(JSON.stringify(obj, null, 2));
のように2スペースで記述すると次のような出力になります。JSON形式になるのでダブルクオーテーションが付きますが、全てのデータが出力されています。
{
"key1": {
"key2": {
"key3": {
"key4": {
"key5": {
"key6": "value"
}
}
}
}
}
}
注意が必要なのは、データ型によっては省略されたり変換されることです。
たとえば次のようなデータをJSON.stringify()
で出力してみます。
const data = {
stringValue: 'value',
nullValue: null,
undefinedValue: undefined,
booleanValue: true,
arrayValue: [1, undefined, null],
};
null
とboolean
は出力されていますが、undefined
が省略されていたり、配列内のundefined
はnull
に置換されています。
{
"stringValue": "value",
"nullValue": null,
"booleanValue": true,
"arrayValue": [
1,
null,
null
]
}
今回は出力を確認するだけなので動作に影響はありませんが、この挙動を知っておいたほうがいいですね。
とはいえ、ログではなくブラウザの表示側にデータをざっと出して確認したい時にJSON.stringify()
は便利なので、使い方次第という気もします。
console.dir(obj, { depth: null });
を使用する
最後はconsole.dir()
を使う方法です。
console.dir()
の第二引数であるoptions
にはdepth
があり、出力する階層の数を指定できます。
depth Non-standard Optional
depth 標準外 オプション
A number representing the number of nesting levels to print when an object contains other objects or arrays. The value null means: print all levels. Defaults to 2.
オブジェクトに他のオブジェクトや配列が含まれる場合に表示する入れ子レベルの数を表す数値。値nullは「すべてのレベルを表示する」を意味する。デフォルトは2。
null
を指定すれば全てのレベルを表示することができるので、console.dir(obj, { depth: null });
と記述します。
深い階層でも全て出力されているのがわかります。
{
key1: {
key2: {
key3: { key4: { key5: { key6: 'value' } } }
}
}
}
JSON.stringify()
で問題になっていたundefined
の省略や置換もされません(当たり前ですが)。
const data = {
stringValue: 'value',
nullValue: null,
undefinedValue: undefined,
booleanValue: true,
arrayValue: [1, undefined, null],
};
{
stringValue: 'value',
nullValue: null,
undefinedValue: undefined,
booleanValue: true,
arrayValue: [ 1, undefined, null ]
}
というわけで、console.log('%o', obj);
でもよくありそうなデータ構造なら問題なく出力できるものの、深い階層のデータを確実に全て出力したい場合にはconsole.dir(obj, { depth: null });
を使うのがベストだというのがわかります。
Discussion