본문 바로가기

💻 내 소개 안녕하세요 엄청짱 프로그래머 손다빈 입니다.
  • 나이 : 96년생
  • 특이사항 : MZ세대, INFJ, 오른손잡이, 아이폰 유저
  • 좋아하는 음식 : 롯데리아, 솥뚜껑 삼겹살, BBQ 황금 올리브
  • 취미 : 프로그래밍, 영화 보기

🥷기술
Unity
Godot
Cpp
Javascript
D3
Vue

🐱 우리집 고양이 소개
츄르 먹은 후 츄르 먹기 전
  • 이름 : 콜라
  • 나이 : 14년생
  • 종 : Nado moreum

📱 개인 프로젝트
🏢 참여한 프로젝트
🌱 내 잔디밭

=== 쓰세요 본문

글 묶음/사탄도 외면한 javascript

=== 쓰세요

초긍정 개발자 다빈맨 2019. 3. 25. 00:17

| == 와 === 연산자에 대한 오해




== 연산자와 === 연산자는 모두 자바스크립트에서 동등함을 비교할 때 사용합니다.

console.log("100" == 100); // true
console.log("100" === 100); // false

이 둘의 차이점을 당장 급하게 이해하고 싶다면 위의 예제 하나로 충분합니다. 그리고 나서 보통 이렇게 설명하곤 합니다.


"== 연산자는 값이 동등한지만 확인하고 === 연산자는 값이 동등하고, 타입까지 동등한지 비교합니다"


이 설명은 정확하지 않지만 시간이 없는 개발자들에게 빠른 이해를 돕게 하는 가성비 좋은 설명이라고는 생각합니다. 그렇다면 이 글을 느긋하게 커피 한잔 마시면서 천천히 읽어도 시간이 남아도는 개발자들이라면 이 연산자에 대한 좀 더 자세한 내용을 알아두실 필요가 있겠네요. 사실 두 연산자의 진짜 차이점은 단순히 타입까지 동등한지 비교하는 것이 아닌, 우리 몰래 암묵적으로 형 변환을 허용하는가 입니다. 이제 가성비 좋은 설명을 대신할 설명을 준비해두었습니다.


"== 연산자는 암묵적 형 변환을 허용하고 === 연산자는 암묵적 형 변환을 허용하지 않습니다"

console.log("100" == 100); // 실제로는 (Number("100") === 100) 로 비교함.
console.log("100" === 100);

자, 이제 됐습니다. 다시 위의 예제를 살펴볼까요? == 연산자의 경우 개발자 몰래 비교할 때 암묵적으로 형 변환을 진행하기 때문에 위와 같이 문자열과 숫자를 비교하는 경우에 문자열을 숫자로 형 변환한 후 비교를 진행하기 때문에 결과는 true가 됩니다.




| == 연산자의 문제점


이 포스트의 제목을 '=== 쓰세요' 라고 지은 이유는 사실 여러분들에게 === 연산자를 쓰라고 강제하고 싶은 마음보다는 == 연산자가 가지고 있는 단점을 피하는 가장 쉬운 방법은 그냥 === 연산자를 사용하는 것이기 때문입니다. 다음 문제점을 살펴봅시다.


1. 복잡한 형변환 규칙


개발자 몰래 형 변환하는 것 까진 좋은데 이 규칙 자체가 워낙 복잡한데다가 지멋대로 일때가 많습니다. 애초에 == 연산자의 진짜 이름이 추상적 동등비교 인 것 부터 코드의 가독성과는 조금 먼 이야기라는게 느껴집니다.



위는 추상적 동등비교 (==) 를 사용했을 때 발생하는 형변환을 정리해 놓은 표인데 Equality_comparisons_and_sameness 에서 확인할 수 있습니다. 이 표를 달달 외우고 다닐 개발자가 몇이나 될지는 모르겠습니다.


2. 예상하기 어려운 형 변환


당신이 결벽이 심한 개발자라서 복잡한 표를 전부 달달 외웠더라도 형 변환을 쉽게 예측하는건 어렵습니다. 자바스크립트의 암묵적 형변환에 대한 특이 사례(물론 제대로 짚고 넘어가면 합리적일테지만)는 여러 존재하지만 그 중 몇개를 추려보았습니다.

console.log(Array(3)==",,"); // true
console.log([0]==[0]); // false
console.log([] == ![]); // true

흠.. 그렇습니다. 이해하기 힘들겠지만 자바스크립트 입장에서는 나름 합리적인 형변환이 이루어집니다. 굳이 어떻게 형 변환 되는지 살펴보자면 첫번째 라인의 경우 일단 배열의 경우 toPrimitive 정의에 의해서 배열은 문자열로 형 변환 됩니다. 때문에 Array(3)은 String(Array(3))로 형 변환 되면서 ",," 가 되고, 결과적으로 true로 비교됩니다. 그렇다면 두번째 라인은 어떨까요? 

console.log("0" == "0"); //true
console.log(new String("0") == new String("0")); //false

두번째 라인의 경우 문자열로 형 변환 되는 두 "0" 이 리터럴인지 아닌지를 생각하면 됩니다. 배열 [0] 이 문자열로 형 변환 될 때 리터럴이 아닌 위 예제에서의 후자의 경우처럼 만들어지기 때문에 false가 됩니다.

console.log([] == ![]); // [] == false

세번째 라인의 경우 동등비교 이전에 위와같이 ! 연산자로 인해서 Boolean 으로 변환되어 비교된다는걸 잊지 않는다면 추론할 수 있습니다.




| === 쓰세요


암묵적 형 변환은 속사정을 들어보면 나름 합리적이지만 예측하기 어려운게 사실입니다. 대부분의 경우 여러분의 예상대로 작동하겠지만 결국 버그는 예측하지 못하는 상황에서 발생합니다. 다시 말하지만 == 연산자의 동작방식을 정확히 이해하지 못하겠다면 그냥 피하는게 답입니다.