kimjeongwonnabout

자바스크립트 동등비교연산자 (==)

자바스크립트에서 헷갈리는 비교연산의 규칙들

자바스크립트에서는 비교연산이 두가지 있다. ===== 로 전자는 동등비교연사자, 후자는 일치비교연산자라고 부르기도 한다. (일단 나는 그렇게 부른다.) 대부분의 자바스크립트 개발자들은 두 비교연산자의 차이점은 비교연산시에 동적으로 타이핑을 하느냐로 알고 있을 것이고, 나도 그랬었다. 그렇다면 아래 표현식들의 결과는 어떻게 나올까?

[] == true;
null == 0;

결론부터 말하자면 둘 다 false가 나온다. 우리는 동등 비교연산==을 하게되면 양쪽의 피연산자의 값을 형변환을 이용한 뒤 일치연산을 하는 것으로 알고있다. 그렇다면 일반적으로 아래와 같은 방식으로 비교할 것이라고 기대한다.

[] == true; // []를 boolean으로 형변환 한다
true == true; // true를 반환한다

null == 0; // null을 0으로 형변환 한다
0 == 0; // true를 반환한다

그런데 왜 둘 다 false가 나오는 것일까? 정답은 자바스크립트는 동등 비교 연산시에 ECMAScript에서 지정한 동등 비교 연산 알고리즘을 통해 형변환을 진행하기 때문이다. 그 중에는 다음과 같은 내용이 있다.

  1. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
  2. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).

그렇다. 양쪽의 피연산자 중 하나가 boolean일 경우 number로 형변환을 한 뒤 비교한다는 내용이다. 왜 동등 비교연산에서 이런 짓을 하는지는 브렌던 아이크씨가 알겠지만, 일단은 동등 비교연산에서는 위의 알고리즘을 따른다는 것이다. 그럼 다시 [] == true가 어떻게 작동하는지 생각 해 보자

[] == true // boolean인 true를 number로 형변환 한다
[] == 1 // true를 number로 바꾸면 1이다. 이제 빈 배열을 number로 형변환 한다
0 == 1 // 빈 배열을 number로 바꾸면 0이 나온다 (1이 아니다) 결국 0과 1을 비교하게 되어서 false가 출력된다.

이런 과정을 거쳐 false가 출력되는 것이었다. 왜 이따위로 만들었는지는 정말 모르겠다.

그럼, null == 0이 안되는 이유는? 역시 동등 비교 연산 알고리즘에 답이 있다. 해당 문서에 nullundefined에 대한 정의는 아래의 두개 뿐이다.

  1. If x is null and y is undefined, return true.
  2. If x is undefined and y is null, return true.

nullundifined는 서로 비교했을 때 true를 반환하고 다른 연산시에는 형변환을 하지 않는다. 그렇기 때문에 null == 0을 했을 때 null은 아예 형변환을 하지 않게되고 그대로 비교하게 되기 때문에 false를 반환하게 된다.

보통 자바스크립트를 학습할 때 동등비교연산== 보다는 일치비교연산===을 사용하라고 배우게 된다. 그리고 사실 ===만 사용하게 되면 위의 문제로 고민할 필요도 없다. 그럼에도 개발자로서 왜? 라는 질문을 해보는 것이 중요하다. 위 사실을 알게 되었든 아니든 ===만을 사용하면 이런 문제를 고민할 필요는 없겠지만 그럼에도 동등비교연산의 매커니즘을 적확히 파악하여 다음과 같은 상황에 대한 처리방법을 생각 할 수 있었다.

만약 어떤 값에 대하여 null이 들어올지 undefined가 들어올지 확실하지 않은 상황에서, if (value == null) {}과 같은 방법으로 nullish한 값에 대한 처리가 가능해 진다.