[클린코드JS] 03. 타입 다루기

Serin-B·2023년 6월 16일
0

클린코드JS

목록 보기
3/15
post-thumbnail

JavaScript는 동적 언어이기 때문에, JavaScript의 변수는 어떤 특정 타입과 연결되지 않고 모든 타입의 값으로 할당 및 재할당이 가능하다.

따라서 내가 현재 다루고 있는 변수의 타입이 무엇인지 검사하고, 내가 의도한 대로 타입을 변환 또는 유지하는 것은 중요하다.

타입의 종류

JavaScript 언어의 타입은 원시 값(primitive)과 객체(object)로 나뉜다. 이 글을 읽는 사람들은 타입에 대한 이해는 있으리라 생각하기 때문에 간단히 정리만 하고 넘어가겠다.

원시값설명
Boolean참(true) 혹은 거짓(false)
Number숫자, NaN("Not a Number")도 Number에 속함
String문자열
Undefined값을 할당하지 않은 변수의 값
Null의도적으로 비어있음을 표현한 값
BigIntNumber의 한계를 넘어서는 큰 숫자 값
Symbol고유하고 변경 불가능한 원시 값, 객체 속성 키로 사용할 수 있음

객체설명
Array배열
Object객체
Function함수. 자바스크립트에서 함수는 '일급 객체'이며, 변수에 함수를 할당할 수 있다.

타입 검사하기

타입을 검사할 수 있는 여러 방법이 있다. 그 중 가장 쉽고 보편적으로 사용하는 방법은 typeof 연산자를 사용하는 것이다.

1. typeof 연산자 사용하기

typeof value 또는 typeof (value)
피연산자의 자료형을 문자열로 반환한다.

console.log(typeof 42); // "number"
console.log(typeof 'blubber'); // string"
console.log(typeof true); // "boolean"
console.log(typeof aaa); // "undefined"

그러나 몇가지 주의할 점이 있다. 첫번째로, NaN은 "Not a Number", 즉 넘버가 아니라는 뜻이지만 number type에 속하기에 아래와 같은 결과가 나온다.

typeof NaN === 'number'

따라서 NaN을 판별하기 위해서는 Number.isNaN()을 사용해야 한다. 단, 유의할 점은 넘버인지 아닌지가 아닌, NaN인지 아닌지를 판별하기 때문에 숫자인지 검사하고 싶을 때 유의하여 사용해야 한다!

Number.isNaN(value)
주어진 값의 유형이 Number이고 값이 NaN이면 true, 아니면 false를 반환한다.

Number.isNaN(3) //false
Number.isNaN('123') //false
Number.isNaN('hello') //false
Number.isNaN(NaN) //true

NaN이 아닌 숫자가 맞는지 검사하기 위해서는 아래처럼 typeof와 Number.isNaN을 함께 사용하거나, 간단하게 함수를 만들어서 사용하는 것이 좋을 것 같다.

typeof value === 'number' && !Number.isNaN(value)
function isNumber(n){
return typeof n === 'number' && !Number.isNaN(n) ? true : false
}

두번째 주의점은 arraynull 검사 결과를 'object' 로 반환한다. 먼저 엄밀히 말하면 arrayobject가 맞지만 우리가 원하는 결과는 아니다. 따라서 원하는 결과를 얻기 위해서는 Array.isArray()를 사용해야 한다.

typeof [1, 2, 4] === 'object'
typeof null === 'object';

Array.isArray(value)
주어진 값이 Array인지 판별하여 boolean 값을 반환한다.

Array.isArray([1, 2, 3]);  // true
Array.isArray({foo: 123}); // false
Array.isArray('foobar');   // false
Array.isArray(undefined);  // false

다음으로 typeof null === 'object' 은 자바스크립트의 오류임을 인정하였으나, 고칠 수 없는 오류라고 한다. 더 자세한 내용이 궁금하신 분들은 아래 게시글을 읽어보시길 추천한다.
"typeof null"의 역사

2. instansceof 사용하기

instansceof value
생성자의 prototype 속성이 객체의 프로토타입 체인 어딘가 존재하는지 판별하여 boolean 값을 반환한다.

function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}
const auto = new Car('Honda', 'Accord', 1998);
console.log(auto instanceof Car); // true
console.log(auto instanceof Object); // true

그런데 프로토타입 체인의 최상단에는 Object가 있으므로, 무조건 생성자 instanceof Objecttrue를 반환한다.

이러한 Object 프로토타입임을 역이용하여 타입을 검사할 수 있는 방법이 있다.

3. Object.prototype.toString.call() 사용하기

모든 객체에는 객체가 텍스트 값으로 표시되거나 객체가 문자열이 예상되는 방식으로 참조 될 때 자동으로 호출되는 toString() 메서드가 존재한다. 그러나 이 메서드가 사용자 지정 개체에서 재정의되지 않으면 toString()은 "[object type]"을 반환한다.

const o = new Object();
o.toString(); // returns [object Object]
Object.prototype.toString.call() //'[object Undefined]'
Object.prototype.toString.call('')//'[object String]'
Object.prototype.toString.call(1)//'[object Number]'
Object.prototype.toString.call([])//'[object Array]'
Object.prototype.toString.call({})//'[object Object]'
Object.prototype.toString.call(null)//'[object Null]'

형변환 주의하기

Javascript는 에러가 나야하는 수식도 어떻게든 처리하려고 애쓴다. 그 결과 아래 사진과 같은 일들이 동작한다. 이러한 형변환은 실제 코드에서 상당히 위험하기 때문에 주의해야 한다.

또한 == 연산자 대신 === 연산자를 사용해야 한다. 동등 연산자는 타입이 다른 피연산자들끼리의 비교를 시도하기 때문이다.

== : 동등 연산자 (Equal Operator)
=== : 엄격한 동등 연산자(Strict Equal Operator)

따라서 위와 같은 상황을 방지하고, 정확하게 타입을 검사하고 사용하기 위해서 반드시 ===를 사용하자!


타입 변환하기

때때로 위와 같은 자바스크립트의 형변환 특징을 활용하여 문제를 해결하는 경우가 있는데, 좋은 습관은 아니라고 생각한다. 원시 래퍼 객체를 사용하여 명시적이고 안전하게 타입을 변환하는 것을 권장한다.

Number(value)
String(value)
Boolean(value)

또는 원하는 타입으로 반환해주는 매서드를 잘 활용하자!

// ex) 문자열에서 배열로 변환을 원할 경우
//1. 스프레드 연산자를 활용한다.
const str = 'hello'
const arr = [...str]
console.log(arr) // ['h', 'e', 'l', 'l', 'o']

//2.String.prototype.split() 매서드를 활용한다.
const str = 'hello world';
const arr = str.split(' ');
console.log(arr); // ['hello','world']

참조

profile
프론트엔드 개발자

0개의 댓글

관련 채용 정보