본문 바로가기

[모던JS] 013. [기본] 비교 연산자(동등비교, 일치비교, 문자열간비교, null==undefined)

codeConnection 2024. 3. 25.

비교 연산자

연산자 기능
== (equal) 같다 / 수학에서는 =가 같다이지만 자바스크립트에서 =는 할당이다.
!= (not equal) 같지 않다
=== (strict equal) 값과 타입까지 같다
!== (strict not equal) 값과 타입까지 같지 않다
> (greater than) 좌항이 우항보다 크다
< (less than) 좌항이 우항보다 작다
>= (greater than or equal) 좌항이 우항과 같거나 크다
<= (less than or equal) 좌항이 우항과 같거나 작다

비교 연산자의 불린형 반환

비교 연산자를 사용하면 값은 불린형으로 반환된다.

  • true : 참
  • false : 거짓
console.log( 2 > 1 ); // true
console.log( 3 <= 2); // false
console.log( "3" === 3); // false / 타입이 다름
console.log(2 !== 1); // true

문자열 간의 비교

자바스크립트에서는 문자열 끼리도 크기 비교가 가능하다.
A to Z에서 Z에 가까울수록 크다고 본다. 이것을 사전편집순 (lexicographical) 비교라 한다.

문자열 비교의 알고리즘

  1. 첫 글자를 먼저 비교. 비교해서 답이 나온다면 그 답을 반환.
  2. 첫번째 문자열이 서로 같은 크기라면 두번째, 세번째 순으로 진행함.
  3. 모든 문자열의 길이가 같다면 같다고 반환함.
  4. 모두 같은데 문자열의 길이가 다르다면 문자열이 더 긴 쪽이 값이 크다고 판단함.
  5. 같은 문자이나 대문자와 소문자를 비교하는 경우 소문자가 더 크다고 판단함. (자바스크립트가 유니코드의 인덱스 크기로 판단하는데, 소문자가 대문자보다 인덱스가 크기 때문.)
console.log('a' > 'z'); // false
console.log('glow' > 'glee'); // ture
console.log('bee' > 'be'); // true

문자열 간 비교할 때 크기 비교

  • a to z : z로 갈수록 크다.
  • 0 to 9 : 9로 갈수록 크다.
  • ㄱ to ㅎ : ㅎ로 갈수록 크다.
  • ㅏ to ㅣ : ㅣ로 갈수록 크다.

한글의 경우 하나의 글자에서 초성, 중성, 종성 순으로 비교한다. 이 경우에도 비교를 하다 종성이 없는 단어가 있다면, 더 긴 문자열을 인덱스가 크다고 판단한다.

console.log( "각" > "가" ); // true

자료형이 다른 값 간의 비교

  • 문자열 - 숫자형의 비교에서는 문자열을 숫자형으로 형 변환한다.
  • 불린값은 true는 1, false는 0으로 형 변환한다.
console.log( "2" > 1 ); // true / "2" 2라는 숫자로  변환한  비교함.
console.log( "01" == 1 ); // true / "01" 1이라는 숫자로  변환한  비교함.
console.log( true == 1 ); // true
console.log( false == 1 ); // true

동등 비교 연산자 (equality operator)와 일치 비교 연산자 (strict equality operator)

동등 비교 연산자(==, !=)는 각 항의 자료형을 떠나 값이 같은지만 비교하는 비교 연산자이고, 일치 비교 연산자(===, !==)는 값과 함께 각 항의 자료형까지 같은지 비교한다.

let a = 0;
console.log( Boolean(a) ); // false

let b = "0";
console.log( Boolean(b) ); // true

console.log( a == b ); true

이 위의 예제를 살펴보겠다.

먼저 변수 a는 숫자 0이다. 숫자 0은 불린값으로 false이다.
그리고 변수 b는 문자 "0"이다. 문자가 공백이 아니라 하나라도 있으면 불린값으로 true이다.
그리고 변수 a와 b를 비교해보니, 0 == "0"이 되었는데, 문자열과 숫자형을 비교하면 문자열을 숫자로 형 변환하기 때문에 위 비교는 같다고 반환된다.
==는 값만 같은지 비교하는 비교 연산자이고, 숫자형과 문자열의 타입도 같은지 비교할 때는 ===를 사용한다.

==를 사용하면 한 쪽을 숫자로 형 변환하지만 ===를 사용하면 형 변환이 발생하지 않는다. 다만 null과 undefined는 ==도 형 변환하지 않는다. 다른 연산자 >, <, <=, >=에서는 형 변환을 한다.

console.log( "2" == 2 ); // true
console.log( false == 0 ); // true
console.log( true != 1 ); // false
console.log( '' == false ); // true
console.log( true === 1 ); // false
console.log( '' !== 0 ); // true

null, undefined에서의 값 비교

null의 값 비교

null의 값을 비교할 때는 조금 특이한 edge case가 있다.

바로 동등 비교 연산자(==)에서는 숫자형으로 형 변환하지 않고, 나머지 비교 연산자에서는 숫자형으로 형 변환 한다는 것이다. (< > <= >=)

먼저 형 변환 편에서 살펴보았듯 null은 숫자형으로 0, undefined는 NaN이 반환된다.

console.log( null > 0 ); // false
console.log( null == 0 ); // false
console.log( null >= 0 ); // true

위의 예제를 보면 null > 0에서는 null이 숫자 0으로 형 변환 되었기 때문에 0은 0보다 큰 게 아니므로 false가 반환되었다.
그리고 null이 0과 같냐는 동등 비교 연산자에서는 null은 형 변환되지 않기 때문에 null과 0은 같지 않으므로 false가 반환되었다.
그리고 마지막 null >= 0에서는 null이 0으로 형 변환되었기 때문에 0은 0과 같거나 크다에서 같은 값이기에 true가 반환되었다.

비교 불가능한 undefined (NaN)

undefined는 숫자형으로 형 변환하면 NaN이 반환되기 때문에 애초에 숫자와 비교가 불가능하다. 그 어떤 비교 연산자를 사용하더라도 무조건 false가 반환된다.

console.log( undefined > 0 ); // false
console.log( undefined < 0 ); // false
console.log( undefined == 0 ); // false

null == undefined // true

다만 undefined가 유일하게 true로 반환하는 값이 있는데 그것은 null이다.
이 경우를 제외하고 undefined는 모든 비교에서 false를 반환한다.

console.log( null == undefined ); // true

연습문제

아래의 표현식에서 true와 false 값을 예측해보시오.

5 > 4
"apple" > "pineapple"
"2" > "12"
undefined == null
undefined === null
null == "\n0\n"
null === +"\n0\n"

해답

5 > 4 // true
"apple" > "pineapple" // false
// p가 a보다 크다.
"2" > "12" // true
//   하나가 숫자형이면 문자열이 숫자형으로  변환 되지만,   문자열이기 때문에 사전순으로 비교한다.
//  "2" "1"  "2" 사전순에서는  크다. (뒤로갈수록 A to Z 처럼 유니코드 인덱스가 큼) 0 to 9 
// 
undefined == null // true
// undefined는 유일하게 null 같은 값으로 본다.
undefined === null // false
// undefined는 유일하게 null 같은 값이지만, 자료형까지 같진 않다.
null == "\n0\n" // true
// null < > <= >= 등에서는 숫자로  변환하지만, ==에서는  변환하지 않고
// null == 값이 같다고 보는  마찬가지로 undefined 뿐이다.
// 물론 그렇다고 우항이 숫자도 아니다. 공백을 제거하더라도 "0" 문자열이다.
null === +"\n0\n" // false
// 우항은 공백을 제거하고 단항 덧셈 연산자를 사용해서 숫자형으로  변환되어
// 숫자 0인데, null 0으로  변환 되더라도 타입까지 같진 않다.

null == undefined는 딱히 논리적인 이유가 있어 보이진 않으니 암기하는 것이 좋겠다.

댓글