JS | 타입체크, 타입변환

JOY·2024년 8월 29일
0

JS

목록 보기
4/18
post-thumbnail

✅ 타입체크

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

✅ implicit coercion(type coericion)

개발자의 의도와 상관없이 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가 아닌 개발자가 직접 타입 변환을 하는 명시적 형변환 지향하자

✅ explicit coercion(type casting)

개발자의 의도에 따라 명시적으로 타입을 변경하는 방법

  • 표준 빌트인(built-in) 생성자 함수 → String(), Number(), Boolean() 을 new 키워드 없이 호출하는 방법
  • 빌트인(built-in) 메서드를 사용하는 방법
  • 암묵적 타입변환
// 문자열 타입으로 변환
String(5) // "5"
(5).toString() 
5+'' 

// 숫자 타입으로 변환
Number("05"); // 5
parseInt("05")
+"05"

// 불리언 타입으로 변환
Boolean({}) // true
!!{}; // 부정 논리 연산자를 두번 사용 

✅ 동등비교 vs 일치비교

동등 비교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() 메서드 사용하기


참고자료
모던 자바스크립트 Deep Dive
클린코드 자바스크립트

profile
모든 일에 진심을 담아서

0개의 댓글