surf core js : 비교 연산자

Dino_·2021년 7월 20일
0

surf javascript

목록 보기
5/28
post-thumbnail

동등 연산자

동등 연산자(==, abstract equality)로 피연산자를 비교할 때는 JavaScript 엔진에 의해 암묵적인 타입 변환(숫자형으로 형반환 되는 것을 꼭 인지해야 한다.)이 먼저 이루어진다.

따라서 좌항과 우항의 타입이 다르더라도 값이 같다면 true를 반환한다.

아래의 예시를 보며 어떤 값이 나올지 예상해보자.

let a = 10;
let b = '10';
console.log(a == b);  //

console.log('' == '0');    // 
console.log('' == 0);    // 
console.log('0' == 0);    // 
 
console.log('false' == false);    // 
console.log('0' == false);    // 
console.log(0 == false);    // 

많이 헷갈린다. 동등 연산자를 사용하면 타입을 변환하여 비교하는 과정에서 의도치 않은 방식으로 동작할 수 있다.

하지만, null check를 하는 경우엔 동등 연산자를 유용하게 사용할 수 있다. 동등 연산자는 null 과 undefined 두 값을 동일하게 취급하고, 두 값을 제외한 다른 값들에 대해서는 항상 false를 반환한다.

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

일치 연산자

일치 연산자(===, strict equality)는 좌항과 우항의 피연산자가 값과 타입이 모두 같은 경우에만 true를 반환한다.

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

하지만, 일치 연산자(strict equality operator) ===를 사용하면 형 변환 없이 값을 비교할 수 있다.

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

alert( 0 === false ); // false, 피연산자의 형이 다르기 때문

기이한 현상

null vs 0

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

위 비교 결과는 논리에 맞지 않아 보인다.

(3)에서 null은 0보다 크거나 같다고 했기 때문에, (1)이나 (2) 중 하나는 참이어야 하는데 둘 다 거짓을 반환하고 있다.

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

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

그런데 (2)에서 동등 연산자 ==는 피연산자가 undefined나 null일 때 형 변환을 하지 않는다.

undefined와 null을 비교하는 경우에만 true를 반환하고, 그 이외의 경우(null이나 undefined를 다른 값과 비교할 때)는 무조건 false를 반환한다.

비교가 불가능한 undefined

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

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

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

(1)과(2)에선 undefined가 NaN으로 변환되는데(숫자형으로의 변환), NaN이 피연산자인 경우 비교 연산자는 항상 false를 반환한다.

undefined는 null이나 undefined와 같고, 그 이외의 값과는 같지 않기 때문에 (3)은 false를 반환한다.

망할 놈들이다 정말.

문자열 비교

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

'사전편집(lexicographical)'순 이라고 불리기도 하는 이 기준을 적용하면 사전 뒤쪽의 문자열은 사전 앞쪽의 문자열보다 크다고 판단된다.

실제 단어를 사전에 실을 때 단어를 구성하는 문자 하나하나를 비교하여 등재 순서를 정하는 것과 같이 자바스크립트도 문자열을 구성하는 문자 하나하나를 비교해가며 문자열을 비교한다.

alert( 'Z' > 'A' ); // true
alert( 'Glow' > 'Glee' ); // true
alert( 'Bee' > 'Be' ); // true

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

두 문자열의 첫 글자를 비교한다.

첫 번째 문자열의 첫 글자가 다른 문자열의 첫 글자보다 크면(작으면), 첫 번째 문자열이 두 번째 문자열보다 크다고(작다고) 결론 내고 비교를 종료한다.

두 문자열의 첫 글자가 같으면 두 번째 글자를 같은 방식으로 비교한다.

글자 간 비교가 끝날 때까지 이 과정을 반복한다.

비교가 종료되었고 문자열의 길이도 같다면 두 문자열은 동일하다고 결론 낸다.

비교가 종료되었지만 두 문자열의 길이가 다르면 길이가 긴 문자열이 더 크다고 결론 낸다.

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

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

차이점 중 하나는 자바스크립트는 대·소문자를 따진다는 것이다.

대문자 'A'와 소문자 'a'를 비교했을 때 소문자 'a'가 더 크다.

자바스크립트 내부에서 사용되는 인코딩 표인 유니코드에선 소문자가 대문자보다 더 큰 인덱스를 갖기 때문이다.

꼭 알아둬야할 것

if절에서 비교 연산자( x == y, x===y )만 다뤘는데, 이게 비교연산자에 초점을 두어야한다.

예를 들어 비교연산자에서 동등 비교 연산자는 묵시적 숫자형 변환을 수행한다.

if("0" == 0) //true

자칫하면 "0" 은 true(빈 문자열이 아니기 때문에), 0은 false로 착각하여 결과가 false를 예상할 수 있다.

하지만 비교 연산자이기 때문에 숫자형 변환을 한다는 것을 알아두자.

만약 if문 안에 단항으로 존재하면 해당 값은 불린형 변환을 수행한다.

if("0") // true

당연하게 생각할 수 도 있지만, 이러한 형 변환 개념이 잘 잡혀있지 않는다면 헷갈릴 수 있다고 생각한다. (나도 그랬으니까)

Reference

profile
호기심 많은 청년

0개의 댓글