본문 바로가기
자바스크립트

[JavaScript공부 - 9] Comparisons(비교)

by 곰돌찌 2019. 2. 1.

학창시절에 수학 교과에서 비교를 하는 문법을 많이 봤음.


* 큼 / 작음 : a > b, a < b

* 크거나 같음 / 작거나 같음 : a >= b, a <= b

* 같음 : a == b ( 프로그래밍에서 a = b에서 =은 할당 연산자임을 기억할것!!!!)

* 같지 않음 : 수학에서는   기호를 사용함! 하지만 자바스크립트에서는 같지 않다라는 기호는 a != b임.


비교의 결과는 Boolean 타입



다른 연산자들과 같이 비교도 값을 리턴함. 이 경우에는 그 값의 타입은 boolean 타입임.


* true : 비교의 결과가 올바름

* false : 비교의 결과가 옳지 않음.


예를 들어 아래의 예시를 보면, 2 > 1은 올바른 식이기 때문에 true를 반환하며 2 == 1은 2와 1이 같은 값이 아니기 때문에 옳지 않은 비교라 false를 반환함.


1
2
3
alert ( 2 > 1); // true
alert ( 2 == 1); // false
alert ( 2 != 1); // true
cs


비교의 결과는 다른 값들과 마찬가지로 변수에 할당될 수 있음!

1
2
let result = 5 > 4// result = true
alert(result); // true
cs


String(문자열)의 비교


한 문자열과 다른 문자열을 크기를 비교하는 기준은 자바스크립트에서는 사전 또는 사전식 순서임.


즉, 문자열은 한 문자 씩 비교를 함.


1
2
3
alert('Z' > 'A'); // true
alert('Glow' > 'Glee'); // true
alert('Bee' > 'Be'); // true
cs

위의 예시를 보면 두 개의 문자열을 비교하는 알고리즘은 간단함!

1. 두개의 문자열의 첫 번째 문자를 비교함.
2. 만약 첫 번째 문자열의 첫 번째 문자가 다른 문자열의 첫 번째 문자보다 크거나 작을 때 첫 번째 문자열은 두 번째 문자열보다 크거나 작기 때문에 더 이상 비교를 하지 않음.
3. 반면에, 두 문자열의 첫 번째 문자가 같을 때, 두 문자열의 다음 문자를 똑같은 방식으로 비교함.
4. 두 개 중 하나의 문자열이라도 끝날 때 까지 비교함
5. 끝까지 했는데 문자열 끝까지 같고 길이도 같다면 그 두 문자열은 같음. 반면에 더 긴 문자열은 큰 걸로 간주함(위의 예시 3번)

위의 예시에서 보면 'Z' > 'A'는 첫 문자에서 바로 비교가 되지만 Glow와 Glee는 문자마다 비교를함.

1. Glow의 G와 Glee의 G는 같음.
2. Glow의 l과 Glee의 l은 같음.
3. Glow의 o와 Glee의 e 중에서 o가 더 크므로 첫 번째 문자가 더 큼.

# 문자열의 비교는 진짜 사전식 순서가 아니고 유니코드의 순서임!

위에서 대략적으로 문자열의 비교는 사전식 순서라고 했지만 사실은 사전식 순서는 아님.

사전식 순서가 아닌 이유는 'A'와 'a'를 비교했을 때 'a'가 더 크다는 것을 알 수 있음. 그 이유는 자바스크립트에서 사용하는 유니코드의 값이 'a'가 'A'보다 더 크기 때문. 


다른 타입들과의 비교



다른 타입의 값을 비교할 때, 자바스크립트는 그 값들을 숫자로 바꾸어서 비교함.


1
2
alert('2' > 1); // true, string '2' becomes a number 2
alert('01' == 1); // true. string '01' becomes a number 1
cs

추가로, boolean타입에서 true는 1, false는 0이 됨.

1
2
alert(true == 1); // true
alert(false == 0); // true
cs


# 재미있는 연결방식!


이런 결과 값도 가능함!


두 개의 값이 같고, 하나의 값은 boolean 값에서 true인데 다른 하나의 값은 boolean 값에서 false임

하지만 비교하면 true가 될 수 있음!


1
2
3
4
5
6
7
let a = 0;
alert(Boolean(a)); // false
 
let b = "0";
alert(Boolean(b)); // true
 
alert(a == b); // true 
cs

자바스크립트 입장에서 보면, 이 결과는 정상적인 것! 7번째 라인에서 a == b의 비교는 문자를 숫자로 비교하기 때문에, String의 "0"은 Number의 0이 되고 이 값들을 비교하기 때문에 true가 반환됨.



엄격한 동등 비교



일반적인 동등 비교 == 는 약간의 문제가 있음. 숫자타입의 0와 boolean타입의 false를 비교할 수 없기 때문


1
alert(0 == false); // true
cs

빈 문자열에도 같은 일이 일어남!

1
alert('' == false); // true
cs


이러한 현상은 동등 비교 ==에 의해서 특정 문자열을 숫자로 자동 변환해주기 때문에 일어남. 즉, 빈 문자열은 false와 마찬가지로 0을 반환하기 때문에 '' == false가 true를 반환하게 됨.


그렇다면 0와 false를 다르지 않게 나오게 하려면 어떻게 해야할까???


해결은 엄격한 동등비교 ===를 사용하는 것임. 엄격한 동등 비교 === 는 형 변환 없이 그 자체로 동등비교를 함!


즉, a와 b가 다른 타입이라면 a === b는 즉시 false로 반환하게 돔



1
alert(0 === false); // false, because the types are different
cs


엄격한 동등 비교 === 외에도 !== 도 존재함! 이는 타입과 값이 모두 다른지를 비교함.


===는 ==에 비해 좀 더 길지만 에러를 방지하는데에는 도움이 되기 때문에 쓰는 걸 권장함!



null과 undefined와 비교하기



null이나 undefined를 다른 값들과 비교할 때, 직관적으로 비교의 결과를 알 수 없음.



◉ 엄격한 동등 비교 === 를 할 때,

  - 두 값은 다른 타입이기 때문에 false를 반환함


1
alert(null === undefined); // false
cs


◉ 일반 동등 비교 == 를 할 때,

  - 일반 동등 비교를 할 때 특이한 규칙이 있음. null과 undefined를 비교하면 true로 나오는데 다른 값들과 비교하면 false가 됨.


1
alert(null == undefined); // true
cs


◉ 다른 비교 <, >, <=, >=

 - bull/undefined는 숫자로 형변환을 함. null은 0이 되고, undefined는 NaN이 됨.



이상한 결과가 도출되다 : null vs. 0



아래의 예시를 보자!


1
2
3
alert(null > 0); // false
alert(null == 0); // false
alert(null >= 0); // true
cs


null과 0을 비교했을 때 수학적으로 보면 굉장히 이상함. 세 번째 라인에서 null이 0보다 크거나 같을 때 true를 반환하는데 첫 번째 라인과 두 번째 라인은 false 로 나타남!


이러한 결과가 나오는 이유는 동등 비교(==)와 일반 비교(>, <, <= , >=)이 다르게 동작하기 때문임.

null은 숫자로 0으로 반환 되기 때문에 null > 0은 false, null >= 0은 true로 반환됨.


그러나 동등비교(==)는 undefined와 null은 특별한 형 변환 없이 동작하기 때문에 null == 0의 결과가 false로 반환됨.



비교할 수 없는 undefined



undefined는 다른 값과 비교할 수가 없음.


1
2
3
alert(undefined > 0); // false
alert(undefined < 0); // false
alert(undefined == 0); //false
cs


0과 비교문들을 돌렸을 때 다 false가 반환되는 것을 알 수 있음!!!


1, 2라인의 비교는 undefined를 NaN으로 형변환 하고 NaN은 특별한 숫자 값이므로 다른 값들과 비교를 해도 false가 반환됨.

3라인의 동등 비교는 undefined는 null과 비교했을 때만 true를 반환하고 나머지 값과 비교는 false를 반환함.



발생가능한 문제를 피하기!



위와 같은 비교문을 다루면서 다양한 예시를 다룬 이유는 가끔 코드를 짤 때 이런 변칙들이 디버깅에 어려움을 겪을 수 있기 때문임.


undefined나 null을 비교할 것이 아니라면 엄격한 동등비교(===)를 사용하는 것을 추천함.


코드를 짤 때 undefined나 null을 비교하는 것을 정확히 알고 있는 경우가 아니라면 undeifned나 null을 일반 비교(>, < , >=, <=)를 사용해서는 안됨. 만약 변수를 undefined나 null을 가질 수 있다면 이를 체크하는 코드를 따로 분리해두는 것이 좋음!

댓글