자바스크립트에는 동등성을 비교하는 네 가지 방식이 있습니다. 이 글에서는 동등성을 판단하는 데 사용되는 고유한 연산자들, 타입 강제 변환(type coercion)이 무엇인지, 그리고 자바스크립트에서 참(truthy) 또는 거짓(falsy) 값을 평가할 때 마주치는 특이한 현상까지 차근차근 살펴봅니다.
엄격한 동등 비교 (===)
엄격한 동등 연산자는 세 개의 등호(===)로 표현됩니다. 이 연산자의 목적은 단순히 값만 비교하는 것이 아니라 타입까지 함께 비교하는 것입니다.
const strictComparison = (a, b) => {
console.log(typeof a);
console.log(typeof b);
return a === b;
}
strictComparison(8, '8'); // false
위 예제의 strictComparison 함수는 두 개의 값을 전달받아 두 값이 서로 엄격하게 같은지 여부를 반환합니다.
언뜻 보면 두 값 모두 8이라는 값으로 같아 보입니다. 하지만 엄격한 동등 연산자는 타입도 함께 검사합니다. 이 예제에서 a에 대해 typeof a를 실행하면 'number'가 반환되고, b에 대해 typeof b를 실행하면 'string'이 반환됩니다.
타입이 서로 다르기 때문에 최종 결과는 false가 됩니다.
=== 연산자의 특이한 비교 사례
자바스크립트의 엄격한 동등 연산자로는 몇 가지 특이한 비교가 가능합니다. 다음은 코딩 면접에서 자주 출제되는 사례들입니다.
| 피연산자1 | typeof 피연산자1 | 피연산자2 | typeof 피연산자2 | 반환값 |
| null | object | null | object | true |
| undefined | undefined | undefined | undefined | true |
| null | object | undefined | undefined | false |
| NaN | number | NaN | number | false |
| false | boolean | "false" | string | false |
| false | boolean | false | boolean | true |
| "" | string | "" | string | true |
| "" | string | undefined | undefined | false |
한 가지 주의할 점은 이 연산자가 배열이나 객체 같은 데이터 구조 간의 비교는 수행하지 않는다는 것입니다. 배열이나 객체를 비교하려면 더 정교한 방법을 사용해야 합니다.
표의 대부분 항목은 타입이 일치하거나 일치하지 않기 때문에 해당 결과가 나옵니다. 유일한 예외는 NaN인데, NaN은 이론상 어떤 값이든 될 수 있어서 서로 같은지 판단할 근거가 없기 때문에 false로 평가됩니다.
엄격한 부등 비교 (!==)
엄격한 부등 연산자는 느낌표와 두 개의 등호(!==)로 표현됩니다. 두 값이 값과 타입 모두에서 같지 않은지를 평가합니다.
const strictInequalityComparison = (a, b) => {
console.log(typeof a);
console.log(typeof b);
return a !== b;
}
strictInequalityComparison("8", 8); // true
위 예제의 strictInequalityComparison 함수는 두 개의 값을 전달받아 두 값이 서로 엄격하게 같지 않은지 여부를 반환합니다.
언뜻 보면 두 값이 같아 보이지만, 엄격한 부등 연산자 역시 엄격한 동등 연산자처럼 타입을 함께 검사합니다.
a에 대해 typeof a를 실행하면 'string'이 반환되고, b에 대해 typeof b를 실행하면 'number'가 반환됩니다. 타입이 서로 다르기 때문에 결과는 true가 됩니다.
!== 연산자의 특이한 비교 사례
엄격한 부등 연산자로도 몇 가지 특이한 비교가 가능합니다. 다음은 면접에서 자주 묻는 사례들입니다.
| 피연산자1 | typeof 피연산자1 | 피연산자2 | typeof 피연산자2 | 반환값 |
| null | object | null | object | false |
| undefined | undefined | undefined | undefined | false |
| null | object | undefined | undefined | true |
| NaN | number | NaN | number | true |
| false | boolean | "false" | string | true |
| false | boolean | false | boolean | false |
| "" | string | "" | string | false |
| "" | string | undefined | undefined | true |
엄격한 동등 연산자와 마찬가지로 객체나 배열 간의 비교는 불가능합니다.
한 가지 더 알아두세요
실제 자바스크립트 개발 과정에서 조건 로직을 작성할 때 사용하게 되는 연산자는 대부분 ===와 !==입니다. 예측 가능한 코드를 위해 이 두 연산자를 기본으로 사용하는 습관을 들이는 것이 좋습니다.
느슨한 동등 비교 (==)
느슨한 동등 연산자는 두 개의 등호(==)로 표현됩니다. 이 연산자는 두 값이 같은지 평가하기 전에 양쪽 값을 공통 타입으로 강제 변환합니다. 이를 타입 강제 변환(type coercion) 또는 타입 변환(type conversion)이라고 부릅니다.
const looseComparison = (a, b) => {
console.log(typeof a);
console.log(typeof b);
return a == b;
}
looseComparison(8, '8'); // true
위 예제의 looseComparison 함수는 두 개의 값을 전달받아 두 값이 서로 느슨하게 같은지 여부를 반환합니다.
언뜻 보면 하나는 숫자이고 하나는 문자열이라 두 값이 달라 보입니다. 하지만 느슨한 동등 연산자는 타입을 보지 않습니다. 비교문은 먼저 타입을 동일하게 만든 뒤 값을 비교하기 때문에, 두 번째 피연산자가 숫자로 변환된 후 비교되어 결과는 true가 됩니다.
== 연산자의 특이한 비교 사례
느슨한 동등 연산자로도 특이한 비교가 가능합니다. 다음은 면접에서 자주 출제되는 사례들입니다.
| 피연산자1 | typeof 피연산자1 | 피연산자2 | typeof 피연산자2 | 반환값 |
| null | object | null | object | true |
| undefined | undefined | undefined | undefined | true |
| null | object | undefined | undefined | true |
| NaN | number | NaN | number | false |
| false | boolean | "false" | string | false |
| false | boolean | false | boolean | true |
| "" | string | "" | string | true |
| "" | string | undefined | undefined | false |
대부분의 항목은 앞서 살펴본 엄격한 동등 비교 섹션과 동일하게 평가됩니다. 주목할 만한 예외는 null과 undefined를 느슨하게 비교하면 true라는 점입니다.
느슨한 부등 비교 (!=)
느슨한 부등 연산자는 느낌표와 하나의 등호(!=)로 표현됩니다. 오직 값만을 기준으로 두 값이 같지 않은지 평가하며, 이를 위해 두 인수를 같은 타입으로 변환하려고 시도합니다.
const looseInequalityComparison = (a, b) => {
console.log(typeof a);
console.log(typeof b);
return a != b;
}
looseInequalityComparison("8", 8); // false
위 예제의 looseInequalityComparison 함수는 두 개의 값을 전달받아 두 값이 서로 느슨하게 같지 않은지 여부를 반환합니다.
언뜻 보면 두 값이 같아 보입니다. 느슨한 부등 연산자 역시 느슨한 동등 연산자처럼 비교 전에 양쪽 피연산자의 타입을 동일하게 강제 변환합니다. 변환 후 값이 같으므로 결과는 false가 됩니다.
!= 연산자의 특이한 비교 사례
느슨한 부등 연산자로도 특이한 비교가 가능합니다. 다음은 면접에서 자주 묻는 사례들입니다.
| 피연산자1 | typeof 피연산자1 | 피연산자2 | typeof 피연산자2 | 반환값 |
| null | object | null | object | false |
| undefined | undefined | undefined | undefined | false |
| null | object | undefined | undefined | false |
| NaN | number | NaN | number | true |
| false | boolean | "false" | string | true |
| false | boolean | false | boolean | false |
| "" | string | "" | string | false |
| "" | string | undefined | undefined | true |
엄격한 동등 연산자와 마찬가지로 객체나 배열 간의 비교는 불가능합니다.
대부분의 항목은 엄격한 부등 비교 섹션과 동일하게 평가됩니다. 주목할 만한 예외는 null과 undefined를 느슨하게 비교하면 false라는 점입니다.
결론
이 글에서는 자바스크립트에서 동등성을 비교하는 네 가지 방법을 살펴보았습니다. 기억해야 할 핵심은 삼중 등호(===)와 이중 등호(==)는 서로 다른 연산자라는 것입니다. 하나는 타입과 값을 모두 엄격하게 평가하고, 다른 하나는 양쪽을 같은 타입으로 강제 변환한 후 값만 평가합니다.
예상치 못한 버그를 줄이고 코드의 의도를 명확하게 드러내기 위해, 실무에서는 타입까지 검사하는 ===와 !==를 사용하는 것이 권장됩니다. 다만 null과 undefined를 동시에 처리해야 하는 특수한 경우에는 ==가 유용할 수 있다는 점도 알아두면 좋습니다.