두 표현식의 차이점
문제를 자세히 들여다보면 ([] == false)와 ([] || true)의 차이는 다음과 같습니다.
첫 번째 경우에는 느슨한 동등 비교(loose equality)를 사용하기 때문에 타입 강제 변환(type coercion)이 개입합니다.
반면 두 번째 경우에는 []를 해당하는 불리언 값(truthy 또는 falsy)으로 평가하게 되는데, 이 과정에서는 내부적으로 타입 강제 변환이 아닌 Boolean() 함수가 사용됩니다.
그럼 이제 두 경우 각각에서 내부적으로 어떤 변환이 일어나는지 하나씩 살펴보겠습니다.
Case 1 — ([] == false)
MDN 문서에 따르면, 서로 다른 데이터 타입 x와 y를 느슨한 동등 연산자(==)로 비교할 때는 다음과 같은 규칙이 순차적으로 적용됩니다.
먼저 불리언 값은 Number() 함수를 통해 숫자로 변환됩니다.
[] == 0 // Number(false) = 0
그다음 객체 타입의 피연산자는 원시 값(primitive value)으로 변환됩니다. 빈 배열은 문자열화되면 빈 문자열이 되죠.
"" == 0
마지막으로 빈 문자열이 숫자로 변환되어 최종 비교가 이루어집니다.
0 == 0
결국 위 비교는 true를 반환합니다.
Case 2 — ([] || true)
이 경우에는 []의 truthy/falsy 여부를 판단하기 위해 내장 함수 Boolean()을 사용해 불리언으로 변환합니다.
Boolean([]) = true
빈 배열은 불리언으로 변환하면 true, 즉 truthy 값입니다. 따라서 논리 OR 연산자(||)는 첫 번째 truthy 값을 그대로 반환하기 때문에 결과가 []가 되는 것입니다.
핵심 정리
같은 빈 배열이라도 맥락에 따라 다르게 동작합니다. == 비교에서는 단계적인 타입 강제 변환을 거쳐 false와 같아지지만, 조건 평가에서는 Boolean() 기준으로 truthy로 취급됩니다. 이처럼 자바스크립트의 암묵적 형변환 규칙을 이해하면 직관에 어긋나 보이는 결과들도 명확히 설명할 수 있습니다.