자바스크립트 핵심컨샙33 #5. == vs === vs typeOf

김동욱·2021년 7월 3일
0

자바스크립트

목록 보기
5/25
post-thumbnail

왜 뚱이가 false를 반환했는지 알아봅시다.🤕

1. == (동등연산자)

동등 연산자(==)는 두 개의 피연산자가 동일한지 확인하며, Boolean값을 반환합니다.
특이한 점은 위의 뚱이처럼 다른 타입의 값들끼리도 연산이 가능합니다.

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

console.log('hello' == 'hello');//true

console.log('2' ==  1);//true

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

두 피연산자의 '타입이 다를 경우', 비교하기 전에 '동일한 타입으로 변환'합니다.

  • 숫자와 문자열을 비교할 경우, 문자열을 숫자로 변환합니다.
  • 하나의 피연산자가 Boolean일 경우, true는 1, false는 0으로 변환합니다.
  • 하나의 피연산자가 객체이고 다른하나가 숫자나 문자열이면, 객체를 valueOf()나toString()를 사용해 기본 데이터 타입으로 변환합니다.
  • 스트링이 빈값이 아닌 글자로 채워져있다면 true로 변환합니다. 하지만 '0'일시에는 0으로 변환합니다(아 햇갈린다)

    동등 연산자는 null 과 undefined 두 값을 동일하게 취급하고, 두 값을 제외한 다른 값들에 대해서는 항상 false를 반환합니다.(자칫하면 둘다 0으로 알게될 수 있으니 주의합시다.)

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

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

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

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

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

1_2. 참조값과 원시값의 비교

var obj = new String("3");
var obj2 = new String("3");
var str = "3";

console.log(obj == obj2);// false
console.log(obj == str);// true

let a = [1,2,3]; 
let b = [1,2,3];

let a_b = a

let e = "text"; 
let f = "te" + "xt";

console.log(a == b);// false
console.log(a == a_b);// true
console.log(e == f);// true

저번 포스팅에서 말했듯이 객체는 '참조값'입니다. obj와, obj2는 값은 같지만 서로 다른 객체를 참조하고있습니다. a, b도 마찬가지 입니다. 그래서 같은 값을 참조하고 있는 a와 a_b는 같습니다.

e와 f는 '원시값'입니다. 타입과 값 모두 같기때문에 true를 반환합니다.
(위의 결과값들은 '일치연산자'에서도 값이 같습니다. 타입만 같다면요)

console.log(0 == "0");// true
console.log(0 == []);// true
console.log(0 == "");// true
console.log("" == []);// true
console.log("0" == "")// false
console.log("0" == []);// false

위에서도 말했듯이 하나가 객체이고 다른하나가 숫자나 문자열이면, 객체를 valueOf()나toString()를 사용해 기본 데이터 타입으로 변환합니다. []이 ''로 변환된다는것을 알았습니다.

그러면 "0" == []는 왜 false가 되는것일까요?🤤

JavaScript에서, 참 같은 값(Truthy)인 값이란 불리언을 기대하는 문맥에서 true로 평가되는 값입니다. 따로 거짓 같은 값으로 정의된 값이 아니면 모두 참 같은 값으로 평가됩니다. (예: false, 0, -0, 0n, "", null, undefined와 NaN 등)
feat.MDN

즉 true 아니면 false가 나올법한 연산에서

false, 0, -0, 0n, "", null, undefined, NaN은 모두 false로 평가 됩니다.😪 나머지는 '전부' true로 평가됩니다.

우리는 값을 비교하기전에 Boolen도 같이 비교하고 있었다는 말이 됩니다.
이것을 Truthy와 Falsy라고 합니다.

그럼 위에서 설명한것을 토대로 밑의 연산을 Boolean으로만 계산해본다면 이와 같이도 볼 수 있습니다.

console.log(0 == "0");// false == false
console.log(0 == []);// false == false
console.log(0 == "");// false == false
console.log("" == []);// false == false
console.log("0" == "")// "0" == false
//(같은 타입이기때문에 형변환이 일어나지 않습니다!)
console.log("0" == []);// "0" == false
//([]가 ''로 바뀌었죠?)

그래서 위의 뚱이가 "0" == []의 연산에서는 형변환이 안되기때문에을 false를 반환했던것입니다.

자칫보면 자바스크립트의 버그처럼 보이지만 모두 내부적으로 논리적인? 연산을 해서 결과를 도출하고 있었습니다.


2. === (일치연산자)

일치연산자는 동등연산자와 다르게 타입변환을 시도하지 않습니다.
다른 타입을 가진 피연산자는 false를 반환합니다. 일치연산자와는 다르게

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

console.log('hello' === 'hello');//true

console.log('2' ===  1);//false

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

일치연산자에서는 null과 undefined를 다르게 봅니다.

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

물론 원시값과 참조값은 비교가 안됩니다.

var obj = new String("3");
var obj2 = new String("3");
var str = "3";

console.log(obj === obj2);// false
console.log(obj === str);// false

2_2. 특이한 상황

여기까지는 저도 고개를 끄덕였습니다. 하지만

console.log(NaN === NaN);  // false?
isNaN(NaN) // true

0 === -0     // true

NaN은 자신과 일치하지 않는 유일한 값입니다...
숫자가 NaN인지 조사하려면 빌트인 함수 isNaN을 사용합시다.
숫자 0도 주의합시다!


3. typeOf

typeof 연산자는 피연산자의 평가 전 자료형을 나타내는 문자열을 반환합니다.
모든 연잔자의 타입을 반환합니다.

let sym = Symbol();
let func = function(){
	return 1 + 1
}
let obj = {
	name : "js"
}

console.log(typeof "javascript");//string
console.log(typeof 123);//number
console.log(typeof 1234567890123456789012345678901234567n);//bigint
console.log(typeof true);//boolean
console.log(typeof undefined);//undefined
console.log(typeof sym);//symbol
console.log(typeof func);//function
console.log(typeof obj);//object
console.log(typeof null);//object???

디버깅을 할때 편한 typeof입니다. 하지만 null이 object로 반환됩니다.
이 현상은 공식 '버그'로 인정되었습니다.

자바스크립트를 처음 구현할 때, 자바스크립트 값은 타입 태그와 값으로 표시되었습니다. 객체의 타입 태그는 0이었습니다. null은 Null pointer(대부분의 플랫폼에서 0x00)로 표시되었습니다. 그 결과 null은 타입 태그로 0을 가지며, 따라서 typeof는 object를 반환합니다. (참고 문서)
feat.MDN

ECMAScript에 수정이 제안(opt-in을 통해)되었으나 제안된 것은 다음과 같습니다.

typeof null === 'null'.

하지만 거절되었다고 합니다.ㅎㅎ😚

profile
안녕하세요. 부산에서 근무하고 있는 프론트엔드 개발자 김동욱입니다. 영어 공부 겸 개발 공부를 위해서 글을 작성하고있습니다.

0개의 댓글