[JS] 동등 연산자와 일치 연산자의 간단한 비교 (+ 짧게 TS)

xii·2023년 8월 12일
1

[JS] 동등 연산자? 일치 연산자?

동등 연산자 ( ==, != )

동등 연산자의 비교

동등 연산자 Equality= 가 2개 연속으로 이어진 비교 연산자입니다.
느슨한 비교를 하기 때문에 다른 타입 간의 값의 비교가 가능합니다.

아래 예시를 보겠습니다.

const a = 77;
const b = '77';

console.log(a == b); // true

anumber 타입의 숫자 77이고, bstring 타입의 문자열 '77'입니다.
그럼에도 둘은 비교가 되고, 일치하다는 결론을 냅니다.

어째서 이런 결과가 나오는 걸까요?

느슨한 비교, 그리고 강제 타입 변환

위에서 설명하였다시피 동등 연산자는 느슨한 비교를 합니다.
느슨한 비교란, 강제 타입 변환을 통해 값이 일치하는지 판단하는 것인데요.
그렇기 때문에 예제에서 문자열 '77'을 숫자 77로 변환하게 됩니다.

느슨한 비교의 순서

강제 타입 변환에는 순서가 있습니다.
다음과 같은 순서를 따르게 되는데요.


const a = 77;
const b = '77';

// 1. 비교하는 두 피연산자가 같은 타입인지 확인합니다.
if(typeof(a) == typeof(b)){
	// 단, NaN의 경우 두 피연산자가 모두 NaN이어도 false를 반환합니다.
  	// 숫자 중 +0과 -0은 같게 취급합니다.
  	// null과 undefined는 같게 취급합니다. 단, 그 외에는 모두 false를 반환합니다.
  	// 
  	console.log(a == b);
}
else { // 2. 같은 타입이 아닌 경우
	// 각각 객체 타입과 원시 타입일 경우, 객체 타입을 원시 타입으로 변환하여 비교합니다.
  	// 2-1. 하나의 피연산자가 심볼이고 다른 하나가 심볼이 아닌 경우, false를 반환합니다.
	// 2-2. 하나의 피연산자가 불리언이고 다른 하나가 불리언이 아닌 경우, 불리언을 숫자로 변환합니다. true는 1로 변환하고 false는 0으로 변환합니다. 그 후 두 피연산자를 다시 느슨하게 비교합니다.
	// 2-3. 한 피연산자가 문자열, 다른 피연산자가 숫자인 경우 문자열을 숫자로 변환합니다. 변환 실패의 결괏값은 NaN이므로, 비교 결과가 false라는 것을 보장합니다.
	// 2-4. 한 피연산자가 Bigint, 다른 피연산자가 숫자인 경우 숫자 값으로 비교합니다. 숫자가 ±Infinity 혹은 NaN이면 false를 반환합니다.
	// 2-5. 한 피연산자가 문자열, 다른 피연산자가 BigInt인 경우 문자열을 BigInt() 생성자와 같은 알고리즘으로 BigInt로 변환합니다. 만약 변환이 실패하면 false를 반환합니다.
  	console.log(a == b);
}

이러한 순서를 통해 비교를 완료하게 됩니다.

일치 연산자 (===, !==)

일치 연산자의 비교

일치 연산자 Strict Equality=가 3개 연속으로 이어진 비교 연산자입니다.
엄격한 비교를 통해 정확한 일치 여부를 파악할 수 있습니다.

아래 예시를 보겠습니다.

const a = 77;
const b = '77';

console.log(a === b); // false

위의 동등 연산자에서는 true가 나왔지만, 이번에는 false가 나왔네요.
왜 그런 걸까요?

엄격한 비교

엄격한 비교란, 타입과 값을 모두 비교하는 것을 말합니다.
즉 숫자 77과 문자열 '77'의 내용은 같아도 타입이 다르므로 다른 값으로 처리하게 되는데요.

이제 각각 어떤 값이 일치하고, 불일치하는지 알아보겠습니다.

엄격한 비교의 관건

const a = 77;
const b = '77';

// 1. 비교하는 두 피연산자가 같은 타입인지 확인합니다.
if(typeof(a) == typeof(b)){
  	// 숫자는 NaN의 경우 무조건 false를 반환하며, +0과 -0은 같은 값으로 봅니다.
  	// undefined와 null은 일치하지 않습니다. undefined는 undefined끼리, null은 null끼리만 일치합니다.
  	// 이외에는 상식에 따릅니다.
}
else { // 2. 같은 타입이 아닌 경우
  console.log(a === b); // 타입이 다르므로 무조건 false를 반환합니다.
}

[TS] 동등 연산자? 일치 연산자?

TypeScript에서는... 동등 연산자가 일치 연산자와 다르지 않습니다.
정확히는, Visual Studio Code 등의 IDE를 기준으로 할 때, 타입이 다른 비교를 동등연산자에 사용하자마자 하단 '문제' 탭에 알림이 발생합니다.

console.log(7 == '7'); 
// 'number'이(가) 'string'과(와) 겹치지 않으므로 이 비교는 의도하지 않은 것 같습니다.

네.. TypeScript에서는 그냥 일치 연산자를 쓰는 게 낫겠네요.


수행 시간 비교

그렇다면 동등 연산자와 일치 연산자의 수행 시간은 얼마나 차이가 날까요?

console.time을 이용해서 간단히 알아보겠습니다.

console.time('Equality1');
console.log(77 == '77'); // true
console.timeEnd('Equality1'); // 3.0877ms (10회 평균 테스트)

console.time('Equality2');
console.log(77 == 77); // true
console.timeEnd('Equality2'); // 3.0636ms (10회 평균 테스트)

console.time('Strict Equality1');
console.log(77 === '77'); // false
console.timeEnd('Strict Equality1'); // 3.0473ms (10회 평균 테스트)

console.time('Strict Equality2');
console.log(77 === 77); // true
console.timeEnd('Strict Equality2'); // 0.031ms (10회 평균 테스트)

보시다시피, 일치 연산자가 전체적으로 우수한 수행 시간을 보입니다.

특히나 완전히 일치할 경우 일치 연산자의 수행 시간이 동등 연산자 대비 100배 가까이 차이가 나게 되는데요.

웬만한 경우에서는 일치 연산자를 사용하는 것이 좋아 보입니다.


참고

MDN Web Docs : https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Equality

profile
내가 그다지 사랑하던 그대여 내 한평생에 차마 그대를 잊을 수 없소이다 내 차례에 못 올 사랑인 줄은 알면서도 나혼자는 꾸준히 생각하리라 자 그러면 내내 어여쁘소서 - 이상, <이런 시>

2개의 댓글

comment-user-thumbnail
2023년 8월 12일

많은 것을 배웠습니다, 감사합니다.

1개의 답글