Home JavaScript의 비교 연산자
Post
Cancel

JavaScript의 비교 연산자

비교 연산자

자바스크립트에서 기본 수학 연산은 다음과 같은 문법을 사용해 표현할 수 있습니다.

  • 보다 큼, 작음 : a > b, a < b
  • 보다 크거나 작거나 같음 : a >= b, a <= b
  • 같음(동등) : a == b. 등호 =가 두 개 연달아오는것에 유의하시기 바랍니다. a = b와같이 등호가 하나일 경우에는 할당을 의미합니다.
  • 같지 않음(부등) : 일반 수학에서 같지 않음을 나타내는 기호인 는 자바스크립트에서는 !=로 나타냅니다. 즉 a != b로 나타낼 수 있습니다.

이 글에서는 자바스크립트의 비교연산자거 어떻게 작동하는지 설명합니다.

불린(Boolean)형 반환

다른 연산자와 마찬가지로 비교 연산자 역시 값을 반환합니다. 반환 값은 불린형입니다.

  • true가 반환되면, “긍정”, ‘참’, “사실”을 의미합니다.
  • false가 반환되면, “부정”, “거짓”, “사실이 아님”을 의미합니다.
1
2
3
console.log( 2 > 1 );  // true
console.log( 2 == 1 ); // false
console.log( 2 != 1 ); // true

반환 된 불린값은 다른 여타 값처럼 변수에 할당 할 수 있습니다.

1
2
let result = 5 > 4; // 비교 결과를 변수에 할당
console.log(result); // true

문자열 비교

자바스크립트는 “사전”순으로 문자열을 비교합니다. “사전 편집(lexicographical)”순 이라고 불리기도 하는 이 기준을 적용하면 사전 뒤쪽의 문자열은 사전 앞쪽의 문자열보다 크다고 판단합니다.
실제 단어를 사전에 실을 때 단어를 구성하는 문자 하나하나를 비교하여 등재 순서를 정하는 것과 같이 자바스크립트도 문자열을 구성하는 문자 하나하나를 비교해가며 문자열을 비교합니다.

1
2
3
console.log( 'Z' > 'A' ); // true
console.log( 'Glow' > 'Glee' ); // true
console.log( 'Bee' > 'Be' ); // true

문자열 비교 시 적용되는 알고리즘은 다음과 같습니다.

  1. 두 문자열의 첫 글자를 비교합니다.
  2. 첫 번째 문자열의 첫 글자가 다른 문자열의 첫 글자보다 크면(작으면), 첫 번째 문자열이 두 번째 문자열보다 크다고(작다고) 결론 내고 비교를 종료합니다.
  3. 두 문자열의 첫 글자가 같으면 두 번째 글자를 같은 방식으로 비교합니다.
  4. 글자 간 비교가 끝날 때까지 이 과정을 반복합니다.
  5. 비교가 종료되었고 문자열의 길이도 같다면 두 문자열은 동일하다고 결론 냅니다. 비교가 종료되었지만 두 문자열의 길이가 다르면 길이가 긴 문자열이 더 크다고 결론 냅니다.

위 예제의 'Z' > 'A'는 위 알고리즘의 첫 번째 단계에서 비교 결과가 도출됩니다. 반면, 문자열 'Glow''Glee'는 복수의 문자로 이루어진 문자열이기 때문에, 아래와 같은 순서로 문자열 비교가 이루어집니다.

  1. GG와 같습니다.
  2. ll과 같습니다.
  3. oe보다 크기 때문에 여기서 비교가 종료되고, o가 있는 첫 번째 문자열 'Glow'가 더 크다는 결론이 도출됩니다.

정확히는 사전순이 아니라 유니코드 순입니다. 자바스크립트의 문자열 비교 알고리즘은 사전이나 전화번호부에서 사용되는 정렬 알고리즘과 아주 유사하지만, 완전히 같진 않습니다. 차이점 중 하나는 자바스크립트는 대, 소문자를 따진다는 것입니다. 대문자 'A'와 소문자 'a'를 비교했을 때 소문자 'a'가 더 큽니다. 자바스크립트 내부에서 사용되는 인코딩 표인 유니코드에선 소문자가 대문자보다 더 큰 인덱스(Index)를 가지고 있기 때문입니다.

다른 형을 가진 값 간의 비교

비교하려는 값의 자료형이 서로 다르면 자바스크립트는 이 값들을 숫자형으로 변환합니다.

1
2
console.log( '2' > 1 ); // true, 문자열 '2'가 숫자 2로 변환된 후 비교가 진행됩니다.
console.log( '01' == 1 ); // true, 문자열 '01'이 숫자 1로 변환된 후 비교가 진행됩니다.

불린값의 경우 true1, false0으로 변환된 후 비교가 이루어집니다.

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

동등연산자 ==의 주의점

1
2
3
4
5
6
7
let a = 0;
console.log( Boolean(a) ); // false

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

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

두 값(a, b)을 비교하면 참이 반환되는데, 값을 논리 평가한 후 비교하면 하나는 참, 하나는 거짓이 반환된다는 점에 의아할 수 있습니다. 그런데 자바스크립트 관점에선 이러한 결과가 자연스러운 결과입니다. 동등 비교 연산자 ==는 피연산자를 숫자형으로 바꾸지만, “Boolean”을 사용한 명시적 변환에는 다른 규칙이 적용됩니다.

일치 연산자

동등 연산자(equality operator) ==0false를 구별하지 못합니다.

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

피연산자가 빈 문자열일 때도 마찬가지로 동일한 문제가 발생합니다.

1
console.log('' == false) // true

이런 문제는 동등 연산자 ==가 형이 다른 피연산자를 비교할 때 피연산자를 숫자형으로 바꾸기 때문에 발생합니다.
빈 문자열과 false는 숫자형으로 변환하면 0이 됩니다.

0false를 구별하는 방법은 다음과 같습니다.

바로 일치 연산자(strict equality operator) ===을 사용하면 형 변환 없이 값을 비교할 수 있습니다.

일치 연산자는 엄격한(strict) 동등 연산자입니다. 값의 동등 여부 뿐만 아니라 자료형의 동등 여부까지 검사하기 때문에 피연산자 ab의 자료형이 다를 경우 a === bfalse를 반환하게 됩니다.

1
console.log(0 === false); // false, 피연산자의 자료형이 다르기 때문

일치 연산자 ===가 동등 연산자 ==의 엄격한 버전인 것처럼 “불일치” 연산자 !==는 부등 연산자 !=의 엄격한 버전입니다.

일치 연산자는 동등 연산자보다 한 글자 더 길긴 하지만 비교 결과가 명확하기 때문에 에러가 발생할 확률을 줄여줍니다.

null이나 undefined와 비교하기

null이나 undefined를 다른 값과 비교할 땐 예상치 않은 일이 발생합니다.

일치 연산자 ===를 사용하여 nullundefined를 비교 두 값의 자료형이 다르기 때문에 일치 비교시 false가 반환됩니다.

1
console.log( null === undefined ); // false

동등 연산자 ==를 사용하여 null과 undefined를 비교 동등 연산자를 사용해 nullundefined를 비교하면 특별한 규칙이 적용돼 true가 반환됩니다.
동등 연산자는 nullundefined를 특별하게 취급합니다.

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

산술 연산자나 기타 비교 연산자 <, >, <=, >=를 사용하여 nullundefined를 비교 nullundefined는 숫자형으로 변환됩니다. null0, undefinedNaN으로 변합니다.

이제 위에서 살펴본 세 가지 규칙들이 어떠한 에지 케이스(edge case)를 만들어내는지, 어떻게 해야 이러한 실수를 하지 않을 수 있는지 설명합니다.

null vs 0

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

위 비교 결과는 논리에 맞지 않아 보입니다. (3)에서 null0보다 크거나 같다고 했기 때문에, (1)이나 (2) 중 하나는 참이어야 하는데 둘 다 거짓을 반환합니다.

이런 결과가 나타나는 이유는 동등 연산자 ==와 기타 비교 연산자 <, >, <=, >=의 동작 방식이 다르기 때문입니다. (1)에서 null > 0이 거짓을, (3)에서 null >= 0이 참을 반환하는 이유는 (기타 비교 연산자의 동작 원리에 따라) null이 숫자형으로 변환돼 0이 되기 때문입니다.

그런데 동등 연산자 ==는 피연산자가 undefinednull일 때 형 변환을 하지 않습니다. undefinednull을 비교하는 경우에만 true를 반환하고, 그 이외의 경우(null이나 undefined를 다른 값과 비교할 때)는 무조건 false를 반환합니다. 이런 이유 때문에 (2)는 거짓을 반환합니다.

비교가 불가능한 undefined

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

위 예제를 보면 undefined는 0과 대조했을때 항상 false를 반환합니다.

이런 결과는 아래와 같은 이유 때문에 발생합니다.

  • (1)과 (2)에선 undefinedNaN으로 변환되는데(숫자형으로 변환), NaN이 피연산자인 경우 비교 연산자는 항상 false를 반환합니다.
  • undefinednull이나 undefined와 같고, 그 외의 값과는 같지 않기 때문에 (3)은 false를 반환합니다.

이런 문제를 겪지 않는 방법

  • 일치 연산자 ===을 제외한 비교 연산자의 피연산자에 undefinednull이 오지 않도록 주의해야합니다.
  • undefinednull이 될 가능성이 있는 변수가 <, >, <=, >=의 피연산자가 되지 않도록 주의해야합니다.

요약

  • 비교 연산자는 불린값을 반환합니다.
  • 문자열은 문자 단위로 비교되는데, 이때 비교 기준은 “사전”순입니다.
  • 서로 다른 타입의 값을 비교할 땐 숫자형으로 형 변환이 이루어지고 난 뒤 비교가 진행됩니다. (일치 연산자는 제외)
  • nullundefined는 동등 비교(==)시 서로 같지만 다른 자료형과는 같지 않습니다.
  • null이나 undefined가 될 확률이 있는 변수가 <, >, <=, >=의 피연산자로 올 때는 주의해야합니다. null, undefined 여부를 확인하는 코드를 따로 추가할것을 권장합니다.
This post is licensed under CC BY 4.0 by the author.