모던 자바스크립트 튜토리얼
ko.javascript.info
자바 스크립트에서 기본 수학 연산은 아래와 같은 문법을 사용해 표현할 수 있다.
a > b
, a < b
a >= b
, a <= b
a == b
등호 =
가 두 개 연달아 오는 것에 유의하자. a = b
처럼 등호가 하나일 때는 할당을 의미한다.≠
는 자바스크립트에선 a != b
로 나타낸다. 할당연산자 =
앞에 느낌표 !
를 붙여서 표시한다.다른 연산자와 마찬가지로 비교 연산자 역시 값을 반환한다.
반환 값은 불린형이다.
true
가 반환 되면, '긍정', '참', '사실'을 의미한다.false
가 반환되면, '부정', '거짓', '사실이 아님'을 의미한다.예시:
alert(2 > 1); // true
alert(2 == 1) // false
alert(2 != 1); // true
반환된 불린 값은 여타 다른 값처럼 변수에 할당 할 수있다.
let result = 5 > 4; // 비교 결과를 변수에 할당
alert(result); // true
자바스크립트는 '사전'순으로 문자열을 비교한다. '사전편집(lexicographical)'순 이라고 불리기도 하는 이 기준을 적용하면 사전 뒤 쪽의 문자열은 사전 앞쪽의 문자열보다 크다고 판단된다.
실제 단어를 사전에 실을 때 단어를 구성하는 문자 하나하나를 비교하여 등재 순서를 정하는 것과 같이 자바스크립트도 문자열을 구성하는 문자 하나하나를 비교해가며 문자열을 비교한다.
alert('Z' > 'A'); // true
alert('Glow' > 'Glee') // true
alert('Bee' > 'Be') //true
문자열 비교 시 적용되는 알고리즘은 다음과 같다.
예시의 'Z' > 'A'는 위 알고리즘의 첫 번째 단계에서 비교 결과가 도출된. 반면, 문자열 "Glow"와 "Glee"는 복수의 문자로 이루어진 문자열이기 때문에, 아래와 같은 순서로 문자열 비교가 이뤄진다.
G
는 G
와 같다.l
은 l
과 같다.o
는 e
보다 크기 때문에 여기서 비교가 종료되고, o
가 있는 첫 번째 문자열 "Glow"
가 더 크다는 결론이 도출된다.✔ 정확히는 사전순이 아니라 유니코드 순이다.
자바스크립트의 문자열비교 알고리즘은 사전이나 전화번호부에서 사용되는 정렬 알고리즘과 아주 유사하지만 완전히 같진 않다.
차이점 중 하나는 자바스크립트는 대·소문자를 따진다는 것이다. 대문자
"A"
와 소문자"a"
를 비교했을 때 소문자"a"
가 더 크다. 자바스크립트 내부에서 사용되는 인코딩 표인 유니코드에선 소문자가 대문자보다 더 큰 인덱스를 갖기 때문이다.
비교하려는 값의 자료형이 다르면 자바스크립트는 이 값들을 숫자형으로 바꾼다.
alert('2' > 1); // true, 문자열 '2'가 숫자 2로 변환된 후 비교가 진행
alert('01' == 1); // true, 문자열 '01'이 숫자 1로 변환된 후 비교가 진행
불린 값의 경우 true
는 1
, false
는 0
으로 변환된 후 비교가 이뤄진다.
alert( true == 1 ); // true
alert( false == 0 ); // true
✔ 흥미로운 상황
같이 일어나지 않을 법한 두 상황이 동시에 일어나는 경우도 있다.
- 동등 비교(
==
)시 true를 반환- 논리 평가 시 값 하나는
true
, 다른 값 하나는false
를 반환let a = 0; alert( Boolean(a) ); // false let b = "0"; alert( Boolean(b) ); // true alert(a == b) // true
두 값을 비교했을 때 참이 반환 되는데, 동등 비교 연산자
==
는 (예시에서 문자열"0"
을 숫자0
으로 변환시킨 것처럼) 피연산자를 숫자형으로 바꾸지만, 'Boolean’을 사용한 명시적 변환에는 다른 규칙이 사용되기 때문이다.
동등 연산자(equality operator) ==
은 0
과 false
를 구별하지 못한다.
alert( 0 === false); // true
피연산자가 빈 문자열일때도 같은 문제가 발생한다.
alert( '' === false); // true
이런 문제는 동등 연산자 ==
가 형이 다른 피연산자를 비교할 때 피연산자를 숫자형으로 바꾸기 때문에 발생한다. 빈문자열과 false
는 숫자형으로 변환하면 0이 된다.
일치 연산자(strict equality operator) ===
를 사용하면 형 변환 없이 값을 비교할 수 있다.
일치 연산자는 엄격한(strict) 동등 연산자다. 자료형의 동등 여부까지 검사하기 때문에, 피연산자 a
와 b
의 형이 다를 경우 a === b
는 fasle
를 즉시 반환한다.
alert( 0 === false ); // false, 피연산자의 형이 다르기 때문이다.
일치 연산자 ===
가 동등 연산자 ==
의 엄격한 형태인 것처럼 "불일치" 연산자 !==
는 부등 연산자 !=
의 엄격한 형태다.
일치 연산자는 동등 연산자보다 한 글자 더 길긴 하지만 비교 결과가 명확하기 때문에 에러가 발생할 확률을 줄여준다.
null
이나 undefined
를 비교할 땐 예상치 않은 일들이 발생한다.
몇가지 규칙을 살펴 본 후, 구체적인 예시를 통해 살펴보도록 하겠다.
일치 연산자 ===
를 이용하여 null
과 undefined
를 비교
두 값의 자료형이 다르기 때문에 일치 비교 시 거짓이 반환된다.
alert( null === undefined ); // false
동등 연산자 ==
를 사용하여 null
과 undefined
를 비교
동등 연산자를 사용해 null
과 undefined
를 비교하면 특별한 규칙이 적용돼 true
가 반환된다.
alert( null === undefined ); // true
산술 연산자나 기타 비교 연산자 < > <= >=
를 사용하여 null
과 undefined
를 비교
null
과 undefined
는 숫자형으로 변환된다. null
은 0
, undefined
는 NaN
으로 변환된다.
이제 위에서 살펴본 세 가지 규칙들이 어떤 흥미로운 에지 케이스(edge case)를 만들어 내는지 알아보자.
null
과 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
이 되기 때문이다.
그런데 동등 연산자 ==
는 피연산자가 undefined
나 null
일 때 형 변환을 하지 않는다.
undefined
와 null
을 비교하는 경우에만 true
를 반환하고, 그 이외의 경우 (null
이나 undefined
를 다른 값과 비교할 때)는 무조건 false
를 반환한다. 이런 이유 때문에 (2)는 거짓을 반환한다.
undefined
를 다른 값과 비교해서는 안된다.
alert( undefined > 0 ); // false (1)
alert( undefined < 0 ); // false (2)
alert( undefined == 0 ); // false (3)
위 예시의 결과를 보면 undefined
는 항상 false
를 반환하고 있다.
이런 결과는 아래와 같은 이유 때문에 발생한다.
(1)
과(2)
에선 undefined
가 NaN
으로 변환되는데(숫자형으로의 변환), NaN
이 피연산자인 경우 비교 연산자는 항상 false
를 반환합니다.undefined
는 null
이나 undefined
와 같고, 그 이외의 값과는 같지 않기 때문에 (3)
은 false
를 반환합니다.위와 같은 에지 케이스를 당장 암기할 필요는 없지만 아래와 같은 방법을 사용해 이런 예외 상황을 미리 예방할 수 있다는 점은 알아두자.
===
를 제외한 비교 연산자의 피연산자에 undefined
나 null
이 오지 않도록 특별히 주의하자.undefined
나 null
이 될 가능성이 있는 변수가 >= > < <=
의 피연산자가 되지 않도록 주의 하자. 만약 변수가 undefined
나 null
이 될 가능성이 있다고 판단되면, 이를 따로 처리하는 코드를 추가하자null
과 undefined
는 동등 비교(==
)시 서로 같지만 다른 값과는 같지 않다.null
이나 undefined
가 될 확률이 있는 변수가 >
또는 <
의 피연산자로 올 때는 주의를 기울자. null / undefined
여부를 확인하는 코드를 따로 추가하는 습관을 들이자.중요도: 5
아래 표현식들의 결과를 예측해보세요.
5 > 4
"apple" > "pineapple"
"2" > "12"
undefined == null
undefined === null
null == "\n0\n"
null === +"\n0\n"
해답
5 > 4 // true "apple" > "pineapple" // false "2" > "12" // true undefined == null // true undefined === null // false null == "\n0\n" // false null === +"\n0\n" // false
해설:
1.5
는4
보다 크기 때문에 명백한 true다.
2. 문자열의 비교는 사전순서가 기준이므로"a"
는"p"
보다 작기 때문에 flase다.
3. 두 피연산자는 문자열이므로, 사전순으로 비교가 이뤄진다. 왼쪽 피연산자의 첫 번째 글자"2"
는 오른쪽 피연산자 첫 번째 글자"1"
보다 크다.
4.null
과undefined
는 같다.
5. 일치 연산자는 형도 체크하기 때문에 형이 다르면 false가 반환된다.
6.null
은 오직undefined
와 같다.
7. 형이 다르므로 false가 반환된다.