JS 파트 1) 2.9 : 비교 연산자

나나·2021년 8월 19일
0

모던 자바스크립트

목록 보기
13/25
post-thumbnail

비교 연산자

  • a가 b보다 큼 : a > b
  • a가 b보다 작음 : a < b
  • a가 b보다 크거나 같음 : a >= b
  • a가 b보다 작거나 같음 : a <= b
  • 같음(동등) : a == b
  • 같지 않음(부등) : a != b

a = b는 동등 연산자가 아닌 할당 연산자이다.

이번 글에서는 비교 시 일어나는 기이한 현상을 포함하여 다양한 자료형을 대상으로 자바스크립트가 어떻게 비교를 하는지에 대해 다룰 예정이다.

불린형 반환

비교 연산자는 불린형으로 반환하며, 반환값이 두 가지다.

  • true : 긍정, 참, 사실
  • false : 부정, 거짓, 사실이 아님

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

문자열 비교

자바스크립트는 사전순으로 문자열을 비교한다.

💡 사전편집(lexicographical)순 : 실제 단어를 사전에 실을 때 단어를 구성하는 문자 하나하나를 비교하여 정한 순서

사전편집순 기준을 적용하면 사전 뒤쪽의 문자열은 사전 앞쪽의 문자열보다 크다고 판단된다.

EX.

📌 문자열 비교 시 적용되는 알고리즘

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

💡 사실, 정확히는 사전순이 아니라 유니코드 순이다.

자바스크립트의 문자열 비교 알고리즘은 사전이나 전화번호부에서 사용되는 정렬 알고리즘과 아주 유사하지만, 완전히 같진 않다.

📌 차이점

자바스크립트는 대·소문자를 따진다는 것이다. 대문자 'A'와 소문자 'a'를 비교했을 때 소문자 'a'가 더 크다. 자바스크립트 내부에서 사용되는 인코딩 표인 유니코드에서는 소문자가 대문자보다 더 큰 인덱스를 갖기 때문이다.

다른 형을 가진 값 간의 비교

🤷🏻‍♂️ 비교하려는 값이 자료형이 다르면?

자바스크립트는 이 값들을 숫자형으로 바꾼다.
EX.

불린값의 경우 true는 1, false는 0으로 변환된 후 비교가 이뤄진다.
EX.

💡 동시에 일어나지 않을 법한 두 상황이 동시에 일어난다?

  • 동등 비교(==)시 true를 반환
  • 논리 평가 시 값 하나는 true, 다른 값 하나는 false를 반환
    EX.

일치 연산자

동등 연산자 ==는 0과 false를 구별하지 못한다.

0 == false를 물어보면 true를 반환한다. 또한 '' == false를 물어봐도 true를 반환한다.

왜❓

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

🤷🏻‍♂️ 그렇다면 0과 false는 어떻게 구별하지?

일치 연산자(strict equality operator) ===

일치 연산자는 엄격한 동등 연산자이다. 자료형의 동등 여부까지 검사하기 때문에 피연산자 a와 b의 형이 다를 경우 a === b는 즉시 false를 반환한다.

null이나 undefined와 비교하기

null이나 undefined를 다른 값과 비교할 땐 예상치 않은 일들이 발생한다. 일단 몇 가지 규칙을 먼저 살펴보자.

1. 일치 연산자 ===를 사용하여 null과 undefined를 비교 ⇛ false

두 값의 자료형이 다르기 때문에 일치 비교 시 거짓이 반환된다.

2. 동등 연산자 ==를 사용하여 null과 undefined를 비교 ⇛ true

동등 연산자를 사용해 null과 undefined를 비교하면 특별한 규칙이 적용돼 true가 반환된다. 동등 연산자는 null과 undefined를 각별한 커플처럼 취급한다. 두 값은 자기들끼리는 잘 어울리지만 다른 값들과는 잘 어울리지 못한다.

3. 산술 연산자나 기타 비교 연산자 <, >, <=, >=를 사용하여 null과 undefined를 비교 ⇛ null은 0, undefined는 NaN으로 변한다.

이제 이 세 가지 규칙들이 어떤 흥미로운 에지 케이스(edge case)를 만들어내는지 알아보자. 이후, 어떻게 하면 에지 케이스가 만들어내는 함정에 빠지지 않을 수 있을지에 대해 알아보겠다.

📌 에지 케이스

1. null vs 0


위 비교 결과 논리가 좀 이상해보인다.

null > 0이 false고 null == 0이 false인데, null >= 0은 왜 true지?

이런 결과가 나타나는 이유는, 동등 연산자 ==와 기타 비교 연산자(<, >, <=, >=)의 동작 방식이 다르기 때문이다.

(1) null > 0에서 거짓을, (3)에서 null >= 0이 참을 반환하는 이유는 (기타 비교 연산자의 동작 원리에 따라) null이 숫자형으로 변환돼 0이 되기 때문이다.

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

2. 비교가 불가능한 undefined

undefined를 다른 값과 비교해서는 안 된다!

기타 비교 연산자로 숫자와 undefined가 비교될 때, undefined는 NaN으로 변환된다. 그리고 NaN이 피연산자일 경우 비교 연산자는 항상 false를 반환한다.

동등 연산자로 undefined를 비교할 때, null 이외의 값과는 같지 않다고 반환하기 때문에 (3) undefined == 0은 false를 반환한다.

⚡ 함정 피하기

이런 에지 케이스들을 꼭 기억하라는 건 아니다. 어차피 개발하다보면 이런 경우도 만나게 되고 점점 익숙해지기 때문에 꼭 암기해야할 필요는 없다. 그냥 예방 차원에서 배운다고 생각하자.

  • 일치 연산자 === 를 제외한 비교 연산자의 피연산자에 undefined나 null이 오지 않도록 특별히 주의해야한다.
  • undefined나 null이 될 가능성이 있는 변수가 <, >, <=, >=의 피연산자가 되지 않도록 주의하자. (명확한 의도가 있다면야 상관없다만...) 만약 변수가 undefined나 null이 될 가능성이 있다고 판단되면, 이를 따로 처리하는 코드를 추가해주자.

💻 과제

📌 답

  1. true
  2. false
  3. true
  4. true
  5. false
  6. false
  7. false

이 글은 https://ko.javascript.info/ 를 참고하여 작성하였습니다.

profile
코린이의 둥당둥당 개발일지

0개의 댓글

관련 채용 정보