자바스크립트 '느슨한 비교' 뽀개기
송용석 책임
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
null
and y isundefined
,return true
. - If x is
undefined
and y isnull
,return true
. - If Type(x) is
Number
and Type(y) isString
, return the result of the comparisonx == ToNumber(y)
. - If Type(x) is
String
and 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
, orSymbol
and Type(y) isObject
, return the result of the comparisonx == ToPrimitive(y)
. - If Type(x) is
Object
and 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/
자바스크립트 하면 제발 타입스크립트 씁시다!! 두 번 씁시다!!