-
자바스크립트의 빈 배열([])은 빈 문자열(""), 0이지만 boolean일 땐 true로 변환되는 이유개발/자바스크립트로의 깊은 잠수 2026. 4. 1. 21:33
JavaScript의 타입 변환 시스템은 봐도봐도 새롭습니다.
암묵적 타입 변환이 일어날 수 있어서, 결과를 예측하기 어려운 경우가 많아요.
그 중에서도 특히 헷갈리는, 빈 배열 (`[]`)의 타입 변환을 정리해 보았습니다.
빈 배열을 문자열과 숫자로 변환하기
먼저 빈 배열을 문자열(string)과 숫자(number)로 각각 변환해 보겠습니다.
객체가 string, number같은 원시값(primitive)으로 변환될 때, 자바스크립트 엔진은 ToPrimitive 추상 연산을 수행합니다.
해당 객체에 대해서 `.toString()`과 `.valueOf()`를 순서대로 시도해요.
객체 중에서도, 배열의 `.toString()`은 내부적으로 `Array.prototype.join()`을 먼저 호출합니다.
빈 배열을 join하면 빈 문자열 (`""`)이 반환됩니다.
그래서 빈 배열을 string으로 변환하면 빈 문자열입니다.
[].toString(); // "" (내부적으로 join을 먼저 호출한다) [].join(); // ""마찬가지로 빈 배열을 number로 변환할 때, ToPrimitive 추상 연산이 수행되므로 내부적으로 `toString()` 호출이 먼저 이루어집니다.
따라서 빈 배열은 빈 문자열이 되고, 빈 문자열은 다시 숫자 0이 됩니다.
Number([]) // [] → "" → 0 Number("") // 0근데 왜 Boolean으로 변환하면 true인가?
참 이상합니다.
빈 배열의 string 변환 결과인 빈 문자열은 Boolean 변환했을 때 false입니다.
빈 배열의 number 변환 결과인 0도 Boolean 변환했을 때 false입니다.
그런데 빈 배열은 Boolean 변환했을 때 true입니다.
Boolean(""); // false Boolean(0); // false Boolean([]); // true
놀랍게도 ToBoolean 변환은 ToPrimitive를 거치지 않습니다.
(Boolean은 원시값이지만, 다른 원시값이랑은 별개로 또다른 타입 변환 방식을 갖고 있는 것입니다..!)
ToBoolean 규칙은 아주 단순합니다.
false로 평가되는 값은 딱 정해져 있습니다.
false, 0, -0, 0n, "", null, undefined, NaN이외의 값들은 모두 true로 평가됩니다(!)
그래서 빈 배열은 Boolean으로 변환하면 true입니다.
왜 boolean만 차별해
그래서, 왜 boolean만 다른 원시값(primitive)들과는 다른 타입 변환 체계를 가지게 된 걸까요?
ECMAScript 명세 전문 저술가인 Axel Rauschmayer 박사의 글에 따르면, 객체에 toBoolean() 같은 메서드를 허용하는 것은 성능 문제를 야기할 수 있기 때문에 객체는 항상 true가 되도록 설계되었습니다.
근본적인 원인은 단축 평가 연산자(`&&, ||`) 때문입니다.
`&&`는 평가될 때 boolean을 반환하지 않고, 피연산자 원본 값을 그대로 반환합니다.
그래서 연속적인 `&&`는 원본 값이 계속 평가되어야 하는 경우를 유발할 수 있습니다.
예시를 들어볼까요?
만약에, `toBoolean()`메서드의 커스터마이징이 가능해서 `new Boolean(false)` 같은 객체가 false로 변환된다고 가정해 봅시다.
그러면 아래와 같은 단축 평가 표현식이 있을때,
new Boolean(false) && 1 && true;이 표현식을 평가하기 위해서 다음과 같은 과정이 진행됩니다.
new Boolean(false) && 1 // 먼저 new Boolean(false)를 boolean으로 평가하기 위해 toBoolean()을 호출합니다. // false라는 것을 알아냅니다. // 하지만 평가 이후에, 평가된 값 false가 아닌 원본 값 new Boolean(false)이 반환됩니다. new Boolean(false) && true // 그러면 또 toBoolean()을 호출해야 합니다!이처럼 연쇄적으로 단축 평가가 이어졌을 때, 계속해서 객체 원본을 변환하는 비싼 변환이 발생하게 되죠.
그래서 ECMAScript 1을 설계할 때 객체가 boolean 변환을 직접 설정(configure)할 수 없도록 결정되었다고 합니다.
그럼 왜 toString이나 valueOf는 괜찮아요?
+ 나 == 같은 연산자는 값의 평가 결과를 사용합니다.
원본 객체가 다음으로 전달되지 않죠.
[] + 1 + 2 // [] → "" (변환 결과인 ""이 다음으로 넘어감) // "" + 1 → "1" // "1" + 2 → "12" // []는 한 번만 변환되면 끝그래서 toString은 괜찮고, toBoolean은 안되는 거랍니다!
참조
Ecma International. (2025). ECMAScript® 2026 Language Specification (ECMA-262, 15th ed.). TC39. https://tc39.es/ecma262/#sec-toprimitive
Rauschmayer, A. (2013, August 20). Why all objects are truthy in JavaScript. 2ality. https://2ality.com/2013/08/objects-truthy.html'개발 > 자바스크립트로의 깊은 잠수' 카테고리의 다른 글
자바스크립트 객체 때문에 에러를 겪는 개발자들을 위한 실무 안내서 (0) 2026.04.15 자바스크립트같은 약타입 언어에 강한 컨벤션을 강제하는 건 쓸데없는 짓일까? 그럴거면 다른거 쓰지 (1) 2026.04.08 어차피 다 똑같은 반복인데 for문만 사용하면 안되는걸까 (1) 2026.03.25 자바스크립트에서 함부로 덧셈하지 마라 (0) 2026.03.18 (x = 1) + 5 는 왜 가능한가? 할당문이 값으로 평가되는 이유 (1) 2026.03.11