IT/언어

[JavaScript] 잊어버리기 쉬운 == 과 === 의 차이

개발자 두더지 2020. 9. 28. 23:22
728x90

== 과 === 의 차이


먼저 문자와 변수의 비교 실험

var a = "1";
var b = 1;

console.log(a==b);
결과:true
console.log(a===b);
결과 :false

== 연산자

 숫자와 문자열을 비교할 때, 문자열을 숫자로 변환한다. JavaScript는 문자열의 숫자 리터럴을 Number형의 숫자로 변환하려고 한다. 처음에 그 문자열의 숫자 리터럴부터 수학적인 값을 이끌어 낸다. 그 다음 가장 가까운 Number형의 수로 반올림한다. 

 즉, == 는 문자열을 숫자와 비교하는 경우 문자열을 숫자로 변환하여 비교한다.

=== 연산자

 피연산자끼리 형을 변환하지 않고 (위에서 표시한 것 처럼) 엄밀하게 비교한다. 이 경우 문자열은 숫자로 변환되지 않으므로, false가 리턴되었다.

 

형 변환에 대해서


 바로 앞에서 == 연산자에서는 형변환이 이루어지는 경우가 있다고 설명했었다. 데이터의 형태는 여러 가지 있지만, 어떻게 변환될까?

Boolean형

 피연산자의 한 쪽이 Boolean형인 경우, 논리 피연산자가 true인 경우 1로, false라면 +0으로 변환된다.

console.log(true==1); // true
console.log(true===1); // false
console.log(false== 0); // true
console.log(false=== 0); //false

오브젝트

 오브젝트를 숫자 또는 문자열과 비교하는 경우, JavaScript는 그 오브젝트의 기본값을 리턴한다. 연산자는 그 오브젝트를 그 오브젝트의 valueOf나 toString이라는 메소드를 이용해 primitive한 값, 혹은 String, 또는 Number의 값으로 변환한다. 이러한 변환을 시도 후 실패했을 때에는 런타임 에러가 발상한다.

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

 위 코드에서는 원시(primitive) 자료형과 String형의 비교하고 있으므로, String형이 primitive형으로 변환됐다. 따라서 아래의 코드는 false이다.

console.log(new String("foo")==new String("foo"));

 다른 오브젝트(라기보다는 인스턴스) 사이의 비교가 되므로, false가 된다.

 따라서 이러한 장난을 치면 어떻게 될까?

var s = new String("foo");
console.log("foo"==s);//결과:true

//valueOf메소드를 다시 작성
s.valueOf=function(){return "boo";}
console.log("foo"==s); //결과:false
console.log("boo"==s); //결과:true

 String형과 primitive형의 문자열을 비교한 경우, 역시 valueOf를 호출하여 문자열과 비교한다.

 또한, undefined와 null의 비교하면 아래와 같이 된다.

console.log(null == undefined);
결과:true
console.log(null === undefined);
결과:false

 

결론


== 연산자는 문자열과 값을 비교할 경우 문자열을 값으로 변환후 가장 가까운 숫자로 반올림하여 비교하고, === 연산자는 값과 자료형을 모두 비교하기 때문에 === 연산자를 사용하는 편이 예상치 못한 오류를 방지할 수 있다.

 


참고자료

developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Identity

qiita.com/PianoScoreJP/items/e43d70ec188c6fed73ed

728x90