js는 동적 타입 언어라 엄격한 타입 체크 필요
▫ typeof
typeof 연산자로 변수를 연산하면 변수에 할당된 값의 데이터 타입 문자열을 반환함
primitive type values는 typeof로 잘 검사되는데
reference type values는 typeof로 검사하는 데 한계 있음_세부 유형을 구분 못함
//primitive type values
typeof '문자열' // "string"
typeof true // "boolean"
typeof Symbol() // "symbol"
//reference type values
typeof {}; // "object"
typeof function() {}; // "function"
typeof []; // "object"
typeof new Date(); // "object"
typeof new String('문자열'); // "object"
reference type을 확인할 때 사용할 대안
▫ Object.prototype.toString.call()
객체의 타입을 나타내는 문자열 반환
Object.prototype.toString.call([]); // "[object Array]"
Object.prototype.toString.call({}); // "[object Object]"
Object.prototype.toString.call(function() {}); // "[object Function]"
Object.prototype.toString.call(new Date()); // "[object Date]"
Object.prototype.toString.call(new String('문자열')); // "[object String]"
+instanceof도 typeof의 대안으로 많이 말하는데 얘는 객체
의 프로토타입 체인에 특정 생성자
가 있는지 확인함
[] instanceof Array // true 배열객체의 프로토타입 체인에 Array.prototype이 있음
그러나 모든 객체는 Object.prototype을 상속받아
객체
instanceof Object
하면 true가
나와 엄격한 타입 체크가 안됨
[] instanceof Object; // true
function() {} instanceof Object; // true
let x = 1;
let str = x + ""; // x는 원시값이고 그 자체가 변하는 게 아니라, 표현식을 평가하기 위해 암묵적으로 새 문자열 "1"을 생성해 사용, 표현식 평가가 끝나면 가비지 콜렉터에 의해 메모리에서 해제됨
console.log(typeof str, str); // string "1"
console.log(typeof x, x); // "number" 1
개발자의 의도와 상관없이 js엔진이 코드의 문맥에 따라 암묵적으로 타입을 변환하는 것_primitive type으로
// 문자열 타입으로 변환
NaN + ''; // "NaN" string 표현식이 평가되는 일시적인 순간에만 NaN이 "NaN"으로 취급됨
// 숫자 타입으로 변환
1 + true; // 2 number
1 + null; // 1 number (1+0)
1 + undefined; // NaN (1+NaN)
+""; // 0 빈 문자열
+[]; // 0 빈 배열
+false; // 0
+null; // 0
+{}; // NaN
+function () {}; // NaN 객체
+[10, 20]; // NaN 값이 2개 이상인 배열
+undefined; // NaN
// 불리언 타입으로 변환
// 💡 js 엔진은 불라언 타입이 아닌 값을 Truthy 값, Falsy 값으로 구분함, Thruthy값은 true로 Falsy값은 false로 암묵적 타입 변환함
// Falsy 값으로 판단하는 값
false, null, undefined, ‘’, 0, -0, NaN
// 나머진 Thruthy 값으로 판단
if(!null) console.log('null is falsy value');
개발자는 자신의 코드에서 암묵적 타입 변환이 발생하는지, 발생한다면 어떤 타입으로 변환되는지, 타입 변환된 값으로 인해 표현식이 어떻게 평가될 것인지 예측할 수 있어야 함, 예측이 결과와 일치하지 않으면 오류 발생 가능
js가 아닌 개발자가 직접 타입 변환을 하는 명시적 형변환 지향하자
개발자의 의도에 따라 명시적으로 타입을 변경하는 방법
// 문자열 타입으로 변환
String(5) // "5"
(5).toString()
5+''
// 숫자 타입으로 변환
Number("05"); // 5
parseInt("05")
+"05"
// 불리언 타입으로 변환
Boolean({}) // true
!!{}; // 부정 논리 연산자를 두번 사용
동등 비교
loose equality (==,eqeq) : 느슨한 동등연산자. 암묵적 타입 변환을 통해 좌항과 우항의 피연산자 타입을 일치시킨 후, 값이 같은지 비교
5 == 5; // true
// 타입은 number 와 string 으로 다르지만, "암묵적 타입 변환"을 통해 먼저 타입을 일치시키고 비교함
5 == "5"; // true
일치 비교
strict equality (===,eqeqeq) : 엄격한 동등연산자, 좌항과 우항의 피연산자가 타입도, 값도 같은지 비교
5 === 5; // true
// 암묵적 타입 변환을 하지 않고 값,타입 둘다 비교
5 === "5"; // false
==은 예측 못한 결과 만들어내 위험함 ===(일치 비교 연산자) 사용 지향하자
// NaN은 자신과 일치하지 않는 유일한 값임
NaN === NaN; // false
// NaN인지 조사 필요하면 -> 빌트인 함수 "Number.isNaN(value)"을 사용
// 타입 변환 없이 인자로 들어온 값이 정확히 NaN이어야만 true 리턴
Number.isNaN(NaN); // true
Number.isNaN(null); // false
Number.isNaN(5/0); // false infinity는 NaN이 아님
Number.isNaN('hello'); // false
Number.isNaN('hello'/'dodam'); // true 연산식땜에 타입변환 시도해서 NaN이 됨
// 정확한 비교를 하려면 -> ES6의 Object.is(value1,value2) 메서드 사용
Object.is(NaN, NaN); // true
+0 === -0; // true
Object.is(-0, +0); // false
더 예측 가능하고 정확한 비교를 하려면 Object.is() 메서드 사용하기