동등 연산자(==)는 두 개의 피연산자가 동일한지 확인하며, Boolean값을 반환합니다.
특이한 점은 위의 뚱이처럼 다른 타입의 값들끼리도 연산이 가능합니다.
console.log(1 == 1);//true
console.log('hello' == 'hello');//true
console.log('2' == 1);//true
console.log(0 == false);// true
동등 연산자는 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
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가 나올법한 연산에서
우리는 값을 비교하기전에 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를 반환했던것입니다.
자칫보면 자바스크립트의 버그처럼 보이지만 모두 내부적으로 논리적인? 연산을 해서 결과를 도출하고 있었습니다.
일치연산자는 동등연산자와 다르게 타입변환을 시도하지 않습니다.
다른 타입을 가진 피연산자는 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
여기까지는 저도 고개를 끄덕였습니다. 하지만
console.log(NaN === NaN); // false?
isNaN(NaN) // true
0 === -0 // true
NaN은 자신과 일치하지 않는 유일한 값입니다...
숫자가 NaN인지 조사하려면 빌트인 함수 isNaN을 사용합시다.
숫자 0도 주의합시다!
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'.
하지만 거절되었다고 합니다.ㅎㅎ😚