자바스크립트 '느슨한 비교' 뽀개기
송용석 책임
Why the heck?
아시는 분은 잘 아시겠지만, 자바스크립트에서의 값 비교는 아주 괴랄(?)하기로 유명합니다.
도대체 왜 이렇게 만들어놓았을까 싶죠!

그래서 더더욱 자바스크립트를 처음 배울 때 비교 연산자(comparison operator) 파트에서 흔히 == 보다는 === 의 사용을 권장한다, 지향하자 따위의 글들을 많이 접해보셨을 겁니다.
이제 우리가 ===를 사용해야겠다는 것은 알겠는데, 그럼 도대체 왜 이런 현상이 일어나는 걸까요?

Let’s dig into it
== 비교 연산자는 형 변환(type conversion)을 야기시킵니다. 만약 비교 대상이 되는 두 값들이 서로 다른 타입이면, 먼저 동일한 타입으로 변환한 후 비교를 하겠다는 이야기인데 이 부분이 그다지 직관적으로 다가오지는 않습니다.
공식적인 ECMAScript 사양 명세의 Section 7.2.14 Abstract Equality Comparison 파트를 보면 보다 상세히 알 수 있는데요, 세부 과정은 다음과 같습니다.
- If Type(x) is the same as Type(y), then
return the result of performing Strict Equality Comparison
x === y. (값이 같은 케이스에서는 어차피 타입 검사도 다 하고 종국에는===를 수행!) - If x is
nulland y isundefined,return true. - If x is
undefinedand y isnull,return true. - If Type(x) is
Numberand Type(y) isString, return the result of the comparisonx == ToNumber(y). - If Type(x) is
Stringand Type(y) isNumber, return the result of the comparisonToNumber(x) == y. - If Type(x) is
Boolean, return the result of the comparisonToNumber(x) == y. - If Type(y) is
Boolean, return the result of the comparisonx == ToNumber(y). - If Type(x) is either
String,Number, orSymboland Type(y) isObject, return the result of the comparisonx == ToPrimitive(y). - If Type(x) is
Objectand Type(y) is eitherString,Number, orSymbol, return the result of the comparisonToPrimitive(x) == y. return false.
Case Study - if('2019' == 2019)
- Type(‘2019’)는 Type(2019)와 같지 않으므로 Strict Equality Comparison
'2019' === 2019는 수행되지 않습니다. - ‘2019’는
null이 아니고, 2019도undefined가 아니므로return true는 수행되지 않습니다. - 2019는
undefined가 아니고, ‘2019’도null이 아니므로return true는 수행되지 않습니다. - Type(‘2019’)는
Number가 아니고, Type(2019)도String이 아니므로 비교x == ToNumber(y)는 수행되지 않습니다. - Type(‘2019’)는
String이고, Type(2019)는Number이므로(finally!), 비교ToNumber(x) == y를 수행한 결과값이return됩니다.
아, 그럼 if('2019' == 2019) 대신 if(2019 == '2019')와 같이 숫자를 우선해 비교하면 한 스텝 정도는 더 일찍 마무리 될 수 있겠..
Why not TypeScript, seriously?
오죽하면 이런 것도 만들까요..
https://dorey.github.io/JavaScript-Equality-Table/
자바스크립트 하면 제발 타입스크립트 씁시다!! 두 번 씁시다!!