서론

JavaScript에서 두 값의 동등성을 비교하는 데에는 ==(느슨한 동등 연산자)와 ===(엄격한 동등 연산자)라는 두 가지 다른 연산자를 사용할 수 있습니다. 초보자에게는 그 구분이 혼란스러울 수 있지만, 이를 이해하는 것은 예측 가능하고 버그 없는 코드를 작성하는 데 근본적입니다. 핵심적인 차이는 데이터 타입을 처리하는 방식에 있습니다.

이 가이드에서는 =====의 동작을 분석하고, 타입 강제 변환의 개념을 설명하며, 어떤 연산자를 사용해야 하는지에 대한 명확한 권장 사항을 제시합니다.

엄격한 동등 연산자 (===)

더 간단하고 예측 가능한 연산자인 엄격한 동등 연산자부터 시작하겠습니다.

엄격한 동등 연산자(===)는 어떠한 타입 변환도 수행하지 않고 두 값이 같은지 확인합니다. 값과 데이터 타입이 모두 동일한 경우에만 true를 반환합니다.

예제:

console.log(7 === 7);       // true (같은 값, 같은 타입)
console.log('hello' === 'hello'); // true (같은 값, 같은 타입)

console.log(7 === '7');     // false (다른 타입: number vs. string)
console.log(true === 1);      // false (다른 타입: boolean vs. number)
console.log(null === undefined); // false (다른 타입)

타입을 변환하려고 시도하지 않기 때문에 동작이 간단하고 이해하기 쉽습니다. 보이는 그대로입니다.

느슨한 동등 연산자 (==)

느슨한 동등 연산자(==)는 더 복잡합니다. 공통 타입으로 변환을 시도한 후 두 값이 같은지 확인합니다. 이 변환 과정을 타입 강제 변환(type coercion)이라고 합니다.

타입 강제 변환 때문에 결과가 때때로 직관적이지 않을 수 있습니다.

예제:

console.log(7 == '7');     // true (문자열 '7'이 숫자 7로 강제 변환됨)
console.log(true == 1);      // true (불리언 true가 숫자 1로 강제 변환됨)
console.log(false == 0);     // true (불리언 false가 숫자 0으로 강제 변환됨)
console.log(null == undefined); // true (언어 사양의 특별한 경우)

console.log('' == 0);       // true (빈 문자열이 숫자 0으로 강제 변환됨)
console.log('\t\r\n' == 0); // true (공백만 있는 문자열이 0으로 강제 변환됨)

타입 강제 변환의 위험성

타입 강제 변환이 편리해 보일 수 있지만, 종종 찾아내기 힘든 미묘한 버그를 유발합니다. 강제 변환 규칙은 복잡하고 예상치 못한 결과를 낳을 수 있습니다.

다음 예제를 생각해보세요.

console.log('0' == false); // true
console.log(0 == false);   // true

// 하지만 이것은 다음을 의미합니다...
console.log('0' == 0);   // true

이러한 종류의 전이적이지만 일관성 없는 논리는 코드를 유지하고 디버깅하기 어렵게 만들 수 있습니다.

또 다른 악명 높은 예제:

console.log([] == ![]); // true
// 왜일까요?
// ![] (빈 배열이 아님)은 false입니다.
// 비교는 [] == false가 됩니다.
// 빈 배열 []은 숫자 0으로 강제 변환됩니다.
// 불리언 false는 숫자 0으로 강제 변환됩니다.
// 비교는 0 == 0이 되어 true가 됩니다.

이것은 느슨한 동등 연산자가 얼마나 혼란스러울 수 있는지를 완벽하게 보여주는 예입니다.

== vs. ===: 비교

연산자 이름 값 비교 타입 비교 타입 강제 변환 예측 가능성
== 느슨한 동등 아니요 낮음
=== 엄격한 동등 아니요 높음

어느 것을 사용해야 할까요? 황금률

경험 많은 JavaScript 개발자들 사이의 압도적인 합의는 다음과 같습니다.

==를 사용해야 하는 구체적이고 의도적인 이유가 없는 한, 항상 ===(엄격한 동등)와 !==(엄격한 부등)를 사용하세요.

엄격한 동등 연산자를 사용하면:

  • 버그 예방: 예상치 못한 타입 강제 변환으로 인한 모든 종류의 버그를 제거합니다.
  • 가독성 향상: 숨겨진 변환이 일어나지 않으므로 코드를 이해하기가 더 쉬워집니다. 의도가 명확합니다.
  • 더 나은 코드 장려: 데이터 타입에 대해 명시적이 되도록 강제합니다. 숫자와 문자열을 비교해야 하는 경우, 작업을 명확하게 하기 위해 직접 변환을 수행해야 합니다(예: Number('7')).

유일한 일반적인 예외: null 또는 undefined 확인

==의 널리 받아들여지는 몇 안 되는 사용 사례 중 하나는 값이 null 또는 undefined인지 동시에 확인하는 것입니다. 왜냐하면 null == undefinedtrue이기 때문입니다.

let myVar;

// 이렇게 하는 대신:
if (myVar === null || myVar === undefined) {
    console.log('변수가 null 또는 undefined입니다');
}

// 이렇게 할 수 있습니다:
if (myVar == null) {
    console.log('변수가 null 또는 undefined입니다');
}

이것조차도 스타일의 문제이며, 많은 개발자들은 명확성을 위해 여전히 명시적인 === 확인을 선호합니다.

결론

=====는 둘 다 동등성을 확인하지만, 서로 바꿔 쓸 수 없습니다. 느슨한 동등 연산자(==)는 자동 타입 강제 변환을 통해 코드에 미묘하고 혼란스러운 버그를 유발할 수 있습니다. 엄격한 동등 연산자(===)는 예측 가능하고 신뢰할 수 있으며, 더 명확하고 유지 관리하기 쉬운 코드로 이어집니다.

===를 기본 선택으로 삼음으로써 더 강력한 JavaScript를 작성하고 많은 일반적인 함정을 피할 수 있습니다. ==는 의도적으로 타입 강제 변환 동작을 활용하려는 드문 경우를 위해 남겨두세요.

Leave a comment