JavaScript ==와 === 차이
JavaScript의 ==와 ===는 두 값이 같은지 비교하고 boolean 값을 반환한다.
핵심 차이는 비교하기 전에 타입을 바꾸는지에 있다.
==는 타입이 다르면 규칙에 따라 값을 변환한 뒤 비교할 수 있다.
===는 암시적 타입 변환을 하지 않고 타입과 값을 함께 비교한다.
일반적인 애플리케이션 코드에서는 ===를 기본으로 사용하면 비교 과정을 예측하기 쉽다.
== 동등 연산자
==는 동등 연산자라고 부른다.
두 항의 타입이 같으면 대체로 ===와 비슷한 방식으로 값을 비교한다.
1 == 1 // true
'hello' == 'hello' // true
true == true // true두 항의 타입이 다르면 JavaScript는 동등 비교 알고리즘에 따라 한쪽 또는 양쪽을 변환한다.
'1' == 1 // true
0 == false // true
'' == 0 // true
null == undefined // true결과만 보면 다른 타입의 값이 같다고 판단되는 것처럼 보인다.
실제로는 비교 중에 숫자 변환 등이 일어난 결과다.
=== 일치 연산자
===는 일치 또는 엄격한 동등 연산자라고 부른다.
두 항의 타입이 다르면 값을 변환하지 않고 바로 false를 반환한다.
'1' === 1 // false
0 === false // false
'' === 0 // false
null === undefined // false타입이 같으면 값을 비교한다.
1 === 1 // true
'hello' === 'hello' // true
true === true // true코드를 읽는 사람은 어떤 타입 변환이 일어날지 추적할 필요가 없다.
비교할 값의 타입이 잘못되었다면 그 문제가 숨겨지지 않고 비교 결과에 드러난다.
문자열과 숫자 비교
HTML 폼에서 읽은 input.value는 숫자처럼 보여도 문자열이다.
<input id="quantity" type="number" value="3" />const input = document.querySelector('#quantity')
console.log(input.value) // '3'
console.log(input.value == 3) // true
console.log(input.value === 3) // false==를 쓰면 문자열 '3'이 숫자 3으로 변환되어 잘못된 타입을 눈치채지 못할 수 있다.
숫자로 다룰 값이라면 의도를 드러내도록 먼저 변환하는 편이 낫다.
const quantity = Number(input.value)
console.log(quantity === 3) // true이렇게 하면 변환은 Number()에서, 비교는 ===에서 담당한다.
변환이 실패할 수 있다면 Number.isNaN() 등으로 결과를 검증해야 한다.
boolean과 숫자 비교
==에서 boolean이 다른 타입과 비교되면 true는 1, false는 0으로 변환될 수 있다.
true == 1 // true
false == 0 // true
false == '' // true사용자가 입력한 값이 빈 문자열인데 false와 같다고 판단되면 조건문의 의도가 흐려진다.
const value = ''
if (value == false) {
console.log('빈 값인지 false인지 알기 어려움')
}빈 문자열인지 확인하려면 그 값을 직접 비교한다.
if (value === '') {
console.log('빈 문자열')
}boolean 조건이 필요하면 Boolean(value) 또는 조건문의 truthy와 falsy 규칙을 명확히 선택한다.
null과 undefined 비교
null과 undefined는 ==에서 서로 같다고 판단되는 특별한 경우다.
null == undefined // true
null === undefined // falsevalue == null은 null과 undefined를 둘 다 확인하는 짧은 패턴으로 의도적으로 쓰이기도 한다.
function hasValue(value) {
return value != null
}
hasValue(null) // false
hasValue(undefined) // false
hasValue(0) // true
hasValue('') // true이 패턴은 null과 undefined만 한 번에 제외한다는 의도가 분명할 때 사용할 수 있다.
팀의 lint 규칙이 ==를 금지하거나 코드를 처음 읽는 사람이 오해할 수 있다면 두 조건을 직접 쓰는 편이 명확하다.
const isMissing = value === null || value === undefined짧은 코드보다 팀이 합의한 읽기 방식을 우선한다.
빈 문자열과 배열의 변환
==의 객체와 원시값 비교에서는 객체가 원시값으로 변환될 수 있다.
[] == '' // true
[] == 0 // true
[1] == 1 // true빈 배열 []은 문자열로 변환하면 ''이 된다.
그 다음 비교 대상에 따라 빈 문자열이 다시 숫자 0으로 변환될 수 있다.
이러한 결과는 규칙을 알면 설명할 수 있지만 업무 코드에서 즉시 의도를 읽기는 어렵다.
배열이 비었는지 확인하려면 길이를 직접 비교한다.
const items = []
if (items.length === 0) {
console.log('빈 배열')
}자동 변환 결과에 기대기보다 확인하려는 속성을 직접 쓰는 편이 낫다.
객체 비교
==와 ===는 둘 다 객체의 내용을 자동으로 깊게 비교하지 않는다.
두 항이 객체라면 같은 객체를 참조하는지 확인한다.
const first = { id: 1 }
const second = { id: 1 }
const same = first
first == second // false
first === second // false
first === same // truefirst와 second는 속성과 값이 같지만 서로 다른 객체다.
내용을 비교하려면 필요한 속성을 직접 비교해야 한다.
const isSameUser = first.id === second.id복잡한 객체라면 도메인에 맞는 비교 함수나 검증 라이브러리를 사용한다.
NaN 비교
NaN은 숫자 타입이지만 자신을 포함한 어떤 값과도 == 또는 ===로 같다고 판단되지 않는다.
NaN == NaN // false
NaN === NaN // false값이 NaN인지 확인하려면 Number.isNaN()을 사용한다.
const result = Number('hello')
Number.isNaN(result) // true전역 isNaN()은 먼저 숫자 변환을 할 수 있으므로 숫자 NaN을 정확히 확인하려면 Number.isNaN()이 더 명확하다.
Object.is와의 차이
JavaScript에는 ==와 === 외에 Object.is()도 있다.
Object.is()는 대부분의 경우 ===와 같은 결과를 내지만 NaN과 부호가 다른 0을 다루는 방식이 다르다.
Object.is(NaN, NaN) // true
Object.is(0, -0) // false
NaN === NaN // false
0 === -0 // true일반적인 조건문에서는 ===로 충분한 경우가 많다.
NaN을 같은 값으로 다루거나 0과 -0을 구분해야 할 때 Object.is()의 차이를 알고 사용한다.
명시적 타입 변환
다른 타입의 값을 비교해야 한다면 ==에 변환을 맡기기보다 의도한 타입으로 먼저 바꾸는 편이 좋다.
const queryPage = '3'
const currentPage = 3
Number(queryPage) === currentPage // true문자열을 비교하려면 문자열로 변환한다.
const productId = 42
const selectedId = '42'
String(productId) === selectedId // true이런 코드는 비교 시점에 어떤 변환을 원했는지 직접 보여 준다.
입력 경계에서 타입을 정리하면 이후 로직은 ===만으로 단순하게 작성할 수 있다.
API 응답, URL query string, input.value, localStorage 값처럼 문자열로 들어오기 쉬운 경계를 특히 주의한다.
조건문의 비교 기준
boolean을 직접 true와 비교할 필요가 없는 경우도 많다.
if (isLoggedIn === true) {
showProfile()
}값이 항상 boolean임이 보장된다면 다음처럼 쓸 수 있다.
if (isLoggedIn) {
showProfile()
}반대 조건은 !isLoggedIn으로 표현한다.
그러나 0, '', null, undefined를 서로 다른 상태로 구분해야 한다면 단순한 truthy 검사 대신 ===로 필요한 값을 정확히 비교한다.
if (count === 0) {
showEmptyState()
}조건문은 값이 존재하는지와 특정 값과 같은지를 구분해야 한다.
선택 기준
기본은 ===와 !==를 사용한다.
타입이 다르면 원하는 타입으로 명시적으로 변환한 뒤 ===로 비교한다.
null과 undefined를 함께 확인하는 의도가 분명하고 팀 규칙에서 허용한다면 value == null을 제한적으로 쓸 수 있다.
인터뷰나 코드 퍼즐을 위해 ==의 모든 변환 결과를 외우기보다 실제 코드에서 변환 지점을 명확하게 만드는 편이 중요하다.
변수를 어떻게 선언할지도 함께 정리하려면 JavaScript var let const 차이를 볼 수 있다.
참고 자료











