== 는 왜 위험할까 (그리고 <=도 조심해야 하는 이유)
자바스크립트를 처음 배울 때
== 말고 === 쓰라는 얘기를 정말 많이 듣는다.
그때는 그냥 “타입까지 비교하니까 더 정확하겠지” 정도로 넘겼다. 그런데 실제로 코드를 읽다 보면, 이게 단순한 취향 문제가 아니라는 걸 알게 된다.
핵심은 하나다.
자바스크립트는 필요하면 타입을 바꿔버린다.
이걸 “타입 강제 변환(Type Coercion)”이라고 부른다. ([MDN Web Docs][1])
1. == 는 값을 비교하기 전에 타입을 바꾼다
1 == "1" // true
이건 많은 사람들이 알고 있다.
문자열 "1"이 숫자 1로 변환된 다음 비교되기 때문이다.
자바스크립트는 타입이 다르면 “어떻게든 비교를 성공시키기 위해” 값을 변환한다. ([Stack Overflow][2])
조금 더 보면 이상해진다.
0 == false // true
"" == false // true
null == undefined // true
여기서 중요한 건 비교하기 전에 무슨 일이 일어나는지 사람이 직관적으로 이해하기 어렵다는 것이다.
2. 그래서 === 는 타입 변환을 하지 않는다
1 === "1" // false
===는 단순하다.
- 타입이 다르면 → 무조건 false
- 타입이 같으면 → 값 비교
이건 사람이 읽는 방식이랑 거의 동일하다.
그래서 결론은 보통 이렇게 정리된다.
==는 “추측해서 맞추는 비교”===는 “있는 그대로 비교”
3. 그런데 <= 도 타입을 바꾼다
여기서 많은 사람들이 놓치는 포인트가 하나 있다.
==만 문제인 게 아니다.
"10" <= 2 // false
"2" <= 10 // true
이건 왜 이런 결과가 나올까?
자바스크립트는 <, <=, >, >= 같은 비교 연산을 할 때
숫자 비교를 하기 위해 타입을 숫자로 바꿔버린다.
"2" <= 10
// -> 2 <= 10
// -> true
즉, 이 연산도 내부적으로는 coercion이 일어난다.
문제는 여기서 끝이 아니다.
"" <= 0 // true
왜냐면
Number("") === 0
이기 때문이다.
이쯤 되면 감이 온다.
==만 위험한 게 아니라 “암묵적으로 타입을 바꾸는 모든 연산자”가 위험하다
4. 왜 이런 설계가 되었을까
자바스크립트는 “유연함”을 목표로 만들어진 언어다.
- 타입이 달라도 알아서 맞춰주고
- 에러 대신 최대한 동작하게 만든다
그래서 이런 일이 가능하다.
"5" - 2 // 3
"5" + 2 // "52"
같은 연산자라도 상황에 따라 다르게 동작한다.
이게 편할 때도 있지만 예측이 어려워지는 순간부터는 버그가 된다. ([GeeksforGeeks][3])
5. 그래서 어떻게 써야 할까
실무에서는 거의 이렇게 정리된다.
1) 비교는 무조건 ===
if (value === 0) { ... }
2) 비교 전에 타입을 명시적으로 맞춘다
Number(input) <= 10
3) “자동 변환”에 기대지 않는다
// ❌
if (value == false)
// ✅
if (Boolean(value) === false)
마무리
정리하면 이렇다.
==→ 비교 전에 타입을 바꾼다===→ 타입까지 포함해서 비교한다<=,<,>→ 숫자 비교를 위해 타입을 바꾼다
그리고 가장 중요한 한 줄
자바스크립트는 생각보다 “많이” 타입을 바꾼다
이걸 모르면 버그를 만들고 이걸 알면 버그를 줄일 수 있다.