console.log로 깊은 객체의 데이터를 모두 출력하지 못함.코딩테스트 문제를 풀이하다가 사소하지만 굉장히 거슬리는 문제를 만나게 되었는데, 배열 자료를 console.log로 출력할 때 깊은 depth의 데이터는 출력되지 않고 자료형만 간소화되어서 표시되는 문제였다.
재귀 함수 등을 이용해서 console.log를 찍어 볼 수는 있지만, 매번 그럴 수는 없으니 해결책을 찾을 필요가 있었다.
재귀 함수는 읽기 어려워서 별로 안좋아한다.

이 문제를 해결하기 위해 Node.js의 설정이나 터미널의 설정을 변경해야하는 줄 알고 이 곳 저 곳을 검색해봤는데 그럴 듯한 힌트나 답을 찾지 못했다. 검색도 뭘 검색해야 될지 키워드를 알아야 찾아볼 수 있다.
30분 검색해보고 못 찾으면 용어든, 원인이든 근본적인 부분을 내가 모르는 것이라고 생각해서 동료분들께 질문했고 그 답을 찾을 수 있었다.
JavaScript엔진, 특히 Node.js 환경에서 console.log를 사용하여 복잡한 자료형을 출력할 때, 성능상의 이유와 가독성을 위해 내부 구조의 모든 정보를 출력하지 않고 일정 깊이 이상에서는 간략화하여 표현하기 때문이다.
즉, Node.js 환경에서 console.log는 원래 이렇게 동작하도록 설계 되어 있다.
실제로 이 문제는 2012년쯤에는 해결책이 필요한 문제였지만, 지금은 오래전에 해결되었다.
당시의 해결책으로 제시된 방법들 몇가지가 있는데, 그 방법을 알면 지금의 해결책에 대한 감사한 마음을 가지게 될 것 같아 좀 더 알아보기로 했다.
재미로 알아보는 것이지만, 나중에 유사한 다른 문제를 만났을때 활용할 수 있지 않을까? 라는 기대도 포함되어 있다.
JSON.stringify 활용한 해결법console.log(JSON.stringify(Object, null, 4));
이 코드는 객체를 JSON 문자열로 변환한다.
null은 replacer 함수로, 모든 속성을 그대로 변환하겠다는 의미이며, 4는 각 요소를 출력할 때 사용할 공백의 수를 지정하여 가독성을 높혀준다.
순환 참조가 있는 객체는 이 방식으로 변환할 수 없고, 함수나 Symbol과 같은 JSON으로 변환할 수 없는 값들은 무시된다. 또한, 배열이나 객체가 매우 크면 문자열로 변환하는 과정에서 성능 문제를 경험할 수도 있다.
function printDeepArray(arr, depth = 0, maxDepth = 4) {
if (depth > maxDepth) {
return '[...]';
}
const output = arr.map(element => {
if (Array.isArray(element)) {
return printDeepArray(element, depth + 1, maxDepth);
} else {
return element;
}
});
return `[${output.join(', ')}]`;
}
const deepArray = [[[[['value'], 3], 2], 1]];
console.log(printDeepArray(deepArray));
maxDepth 매개변수는 출력할 최대 깊이를 제어한다. 필요에 따라 이 값을 조정하여 더 깊은 또는 더 얕은 depth의 데이터를 출력할 수 있다. 이 방법은 외부 라이브러리나 모듈에 의존하지 않으므로, 어떤 환경에서든 사용할 수 있는 장점이 있다.
단, 이 방법은 배열에 한정된 예제이며, 객체나 다른 복잡한 데이터 구조를 처리하기 위해서는 함수를 적절히 확장하거나 조정해야 한다.
util.inspect.defaultOptions을 활용한 방법require("util").inspect.defaultOptions.depth = null;
console.log(myObject);
이 방법을 사용하면 console.log의 탐색 깊이를 제어할 수 있습니다. null값을 적용하면 depth의 끝까지 탐색하도록 동작합니다.
console.dir 메서드를 활용한 해결// console.dir(obj[, options])
console.dir(obj, { depth: null });
이 메서드는 객체를 출력하기 위한 메서드로서 사용된다. 현 시점에서 객체를 출력할 때 console.log를 사용한 것이 잘못된(?) 사용법인 셈이다.
옵션의 depth를 null 을 넘겨주면 해당 객체의 가장 깊은 depth까지 탐색한다.
Node.js 공식 문서에 따르면 console.dir이 받는 매개 변수는 다음과 같다.
showHidden <Boolean> : true인 경우 객체의 열거 불가능 속성과 기호 속성도 표시됩니다. 기본값: false.depth <Number> : 객체의 형식을 지정하는 동안 반복할 횟수를 util.inspect()에 알려줍니다. 이는 크고 복잡한 객체를 검사하는 데 유용합니다. 무한정 반복되게 하려면 null을 전달합니다. 기본값: 2.colors <Boolean> : true인 경우 출력은 ANSI 색상 코드로 스타일이 지정됩니다. 색상은 사용자 정의할 수 있습니다. util.inspect() 색상 사용자 정의를 참조하세요. 기본값: false.깊은 depth의 객체를 출력하기 위한 방법으로 다양한 방법이 시도되었던 것을 알아보았다.
그리고 console 객체 안의 다양한 메서드들을 알아볼 수 있었는데, 다른 메서드들은 나중에 좀 더 차분히 공부하기로 하고 오늘 한가지 확실하게 배운 것은 console.log는 로깅을 위해서 사용하는 것, console.dir는 객체의 전체 데이터를 보기 위해 사용한다는 것이다.
Node.js document - console.dir
stack overflow - How can I get the full object in Node.js's console.log(), rather than '[Object]'?