본문 바로가기

[코드팩토리] 타입 변환 (명시적 & 암묵적) (Coercion)

codeConnection 2024. 3. 3.

자바스크립트에는 Number type, String type 등 여러가지 데이터 타입이 있다.

그 데이터 타입을 변환하는 방법으로 명시적 방법과 암묵적 방법이 있다.

암묵적 타입 변환

자바스크립트에서는 암묵적으로 타입이 변환되는 경우가 있다.

명시적으로 내가 의도해서 타입을 바꾼 것이 아니라 암묵적으로 데이터 타입이 바뀌어 버리는 경우를 이야기하는데 실무에서 이를 의도적으로 쓰는 일은 없다. 또한 암묵적으로 타입이 변환되는 경우를 알아야 같은 값을 보여준다 하더라도 가독성이 떨어지는 지저분한 코딩을 하지 않을 수 있기 때문에 이를 의도해서 쓰진 않더라도 알고는 있어야 한다.

다른 언어에서는 애초에 이런 코드의 입력 자체를 허용하지 않는데 자바스크립트에서만 코드 입력 자체가 허용되는 특이한 경우이기도 하다.

 

예를 들어 숫자와 문자를 더하면 문자가 된다.

let age = 32;

let test = age + '';
console.log(typeof test, test);

age라는 변수를 만들고 값을 32로 할당했다.

그리고 test라는 변수를 만들고 age와 공백이라는 스트링을 더했다.

age는 32로 Number 타입이고 공백은 따옴표로 감싸져 있으니 String 타입인데, 이 둘을 더해서 test라는 변수에 담아

test라는 변수의 타입과 그 값을 출력해보니 아래와 같이 콘솔에 출력된다.

number + string = string이 되었음을 확인할 수 있다.

 

그리고 실무에서는 이런 경우가 발생할 수 있다.

1번줄을 보면 스트링인 48과 넘버인 6을 더하라고 했는데, 486으로 결과가 출력되었다. 숫자끼리 더한 것이라면 54가 되어야 맞지만, 6도 문자열로 해석하고 문자끼리 이어 붙인 것이다.

 

2번줄과 3번줄은 곱셈과 뺄셈인데, 이는 또 정상적으로 계산한 것을 볼 수 있다.

이것은 문자열과 문자열의 곱셈이나 뺄셈은 없고 덧셈만 있기 때문에 나온 결과이다.

test0과 test의 변수를 확인해보니, '48' + 6 은 string으로 암묵적으로 데이터 타입이 변환되었고,

'98' * 2는 number로 암묵적으로 변환되었음을 확인할 수 있다.

명시적 타입 변환

toString() : 스트링 타입으로 바꾸기

기본형 : 타입을바꿀변수명 / (또는 값).toString();

 

toString에서 대소문자 사용에 유의해야 한다.

예시를 보자.

let age = 32;

let stringAge = age.toString();
console.log(typeof stringAge, stringAge);

코드해석

let으로 age라는 변수를 만들고 값으로 32를 할당했다. 이 때 age는 숫자이므로 데이터 타입은 Number가 된다.

다시 stringAge라는 변수를 만들고, age라는 변수를 toString()하여 string 데이타 타입으로 바꾸어 값으로 할당한다.

그리고 콘솔에 age라는 변수를 string 타입으로 바꾸어 담은 stringAge의 타입을 출력해보고, 실제 stringAge의 값이 무엇인지 콘솔에 출력해본다.

그러면 콘솔에 string타입과 32라는 답이 나온다.

toString()은 number type에서 toString 뿐만 아니라 Boolean 타입의 True, False나 Infinity도 Infinity.toString() 형태로 데이터 타입을 명시적으로 변환할 수 있다.

parseInt() : 정수 타입으로 바꾸기 (0, 1, 2, 3, 4 등...)

Int에서 i는 대문자임에 유의

기본형 : parseInt('바꿀문자열');

 

parseFloat() : 실수 타입으로 바꾸기 (0.01 등...)

기본형 : parseFloat('바꿀문자열');

 

위 사진을 보면 문자열인 '0.99'를 parseInt로 바꾸면 0.99가 표현되는 것이 아니라 0으로 표현된다.

이것을 parseFloat로 바꾸니 0.99 그대로 출력이 되었다.

연산자(Operator)를 사용하기

'문자열로 쓰여진 숫자' 앞에 연산자를 넣으면 데이터 타입이 number 타입으로 변환된다.

console.log(typeof +'1', +'1');

Boolean 타입으로의 변환

실무에서도 많이 쓰이는 형태이다.

자바스크립트가 조금 특이하게 해석하는 부분이다. 다른 언어와 공통되는 것은 아니다.

자바스크립트에서는 문자열에 어떠한 데이터라도 담겨 있으면 불리언값으로는 True라고 보고, 문자열이 아무것도 없으면 False라고 판단한다.

 

여기서 앞에서 배운대로 ! 느낌표를 하나 넣으면 아니다라는 반대 개념을 갖게 되는 이 성질을 string 앞에 붙이면 Boolean 타입으로 변환된다. ! 하나는 아니다, !!는 아니다의 아니다이니 맞다가 된다.

console.log(typeof '장원영');
console.log(typeof !'장원영');

위의 코드를 보면 '장원영'이라는 데이터 타입은 String이다.

그런데 아랫줄의 코드에서 !를 하나 붙였더니 '장원영'은 Boolean 타입이 되었다. 그리고 불리언의 값은 원래 '장원영'이라는 문자가 뭐라도 들어있었기 때문에 True였는데 False로 바뀌게 된다.

console.log(!'장원영');

위와 같이 입력해보면 콘솔에 '장원영'이 아니라 이 불리언값이 가지고 있는 False라는 값이 출력된다.

 

'' 따옴표 안에 아무 값도 없으면 이는 True가 아니라 False이다. 그러나 스페이스바로 공백 하나라도 넣으면 문자가 있다고 보고 True 상태가 된다.

console.log(!''); // '' 아무것도 없는 상태, 즉 False였는데 !반대이므로 Ture로 출력. 
console.log(!' '); // ' ' 공백 한 칸이 있는 상태, 즉 True였는데 !반대이므로 False로 출력.

!!를 두개 넣으면 아니다의 아니다니까 원래의 값을 확인할 수 있다.

 

// 아래는 !!를 두개 넣어 원래 상태를 확인하는 것이다.

console.log(!!0); // 숫자 0이므로 이는 스트링이 아니라 False다.
console.log(!!'0'); //  스트링 0이므로 이는 True다.
console.log(!!'false'); // false가 진짜 false가 아니라 스트링으로 넣은 false이기에 true다.
console.log(!!false); // 진짜 false이므로 false다.
console.log(!!undefined); // undefined의 불리언값은 false다.
console.log(!!null); // null의 불리언값은 false다.

 

정리

'' 따옴표로 문자열을 한 글자라도 넣게 되면 불리언값은 True 이다. (스페이스바 공백도 포함)

이 외의 숫자나 undefine, null 등의 모든 값은 False 상태이다.

이 데이터 타입에 !를 하나라도 넣는 순간 데이터 타입 자체가 불리언으로 바뀌게 된다.

 

외우기 어렵다면 False인 상태에 대해서만 외우면 된다.

  • 아무 글자도 없는 String
  • 값이 없는 경우
  • 0 (0은 불리언에서 False, 1은 True)
console.log(!!'', typeof !!''); // 아무 글자도 없는 string

let age;
console.log(!!age, typeof !!age); // 아무 값이 없는 경우
console.log(!!0, typeof !!0); // 0

 

 

 

console.log(typeof null);
console.log(typeof !null);
console.log(typeof undefined);
console.log(typeof !undefined);

 

그런데 문자열은 '' 값이 안 들어 있으면 False이고 스페이스바이든 뭐든 한 글자라도 스트링이 들어가면 True타입이었지만,

오브젝트 타입과 어레이 타입은 값이 들어있지 않더라도 True가 된다.

console.log(!!{}); // object 타입. True
console.log(!![]); // array 타입. True

 

 

 

 

 

출처 : https://www.youtube.com/watch?v=ZOVG7_41kJE&t=3277s

 

댓글