본문으로 바로가기
반응형

 

자바스크립트 형 변환

 

자바스크립트는 타입 검사가 매우 유연해서, 변수의 타입이 정해져 있지 않고 대입 시마다 계속 변한다.
즉, 같은 변수에 다른 타입의 데이터를 계속 새로 할당할 수 있다.

 

① 묵시적(Implicit) 형 변환

자바스크립트는 특정 타입 값이 기대되는 곳에 다른 데이터가 오면 자동으로 타입을 변환한다.
다음과 같은 규칙이 있다.
(좀 복잡해 보이는데.. 사실 외울 것은 아니고 정리 용도로 아래와 같이 작성했다.)

 

1) + 연산

 - Object 끼리 연산 시, Primitive 타입으로 변환한다.
 - 한 쪽이 String이라면 String으로 변환한다.
 - 그 외의 경우에는 Number 타입으로 변환한다.
   (true는 1, false는 0이다.)

console.log(null + undefined); // ''

console.log({} + {});          // '[object object][object object]'
console.log([] + []);          // ''
console.log([] + new Date());  // (A date string)
console.log('' + []);          // ''

console.log('' + 1);           // '1'
console.log('' + true);        // 'true'

console.log(1 + false);        // 1
console.log(1 + true);         // 2
console.log(true + true);      // 2

 

2) - , *, /, ++, -- 연산

- 숫자 형태로 변환한다. 숫자가 안되는 경우에는 NaN(Not a Number)가 반환된다.
  (NaN은 숫자가 아니라는 의미)

console.log(-'1');   // -1
console.log([]-'1'); // -1
console.log([]-{});  // NaN

 

3) 동등 연산자( ==, != )

- null 과 undefined는 동일하다.
- 한 쪽이 숫자고 한 쪽이 문자열이면 문자열을 숫자로 변경해서 비교한다.
- boolean 타입이 있으면 숫자로 바꾸고 비교한다.
- 한 쪽이 객체면 원시 타입으로 변경하고 비교한다.

console.log(null == undefined);   // true

console.log(1 == '1');            // true

console.log(true == 0);           // false
console.log(true == '1');         // true

console.log([1] == 1);            // true
console.log(['1'] == '1');        // true

 

4) 비교 연산자(>, >=, <, <=)

- 한 쪽이 객체면 원시 타입으로 바꾸고 비교한다.
- 둘 다 문자열이면 알파벳 순서로 비교한다.(앞 쪽이 작음)
- 한 쪽이 숫자면 숫자로 변경하고 비교한다.(문자(숫자가 아닌) / 숫자는 비교 안되고 false 반환)

console.log([2] > 1);   // true
console.log([2,1] > 1); // false

console.log('b' > 'a'); // true

console.log('2' > 1);   // true
console.log(2 < 'abs')  // false

 

5) in 연산자

- 좌측 피연산자가 문자열이면 문자열로 바꾼다.

console.log('1' in { 1: '' })  // true
console.log(1 in { 1: 'a' })   // true
console.log(1 in [ 'a', 'b' ]) // true

 

6) 논리 연산자, 삼항 연산자( ? : ), 조건/반복문

- boolean 타입이이 아는 경우 boolean 타입으로 바꾼다.
- truthy : 자바스크립트에서 true로 취급되는 것 → [true, {}, [], 문자열, 정수, 실수]
- falsy : 자바스크립트에서 false로 취급되는 것 → [false, '', null, undefined, 0, -0, NaN]

 

 

② 명시적 형 변환

보통 묵시적인 형 변환을 많이 사용하지만, 명시적으로도 변환은 가능하다.
프로그래밍 중, 묵시적인 변환으로 인해 원하지 않는 변환이 일어날 수 있어 그러한 상황을 피하기 위해 사용할 수 있다.

명시적 타입 변환을 위해서 자바스크립트는 다음과 같은 전역 함수를 제공한다.

 

1) 숫자로 변환하는 전역 함수
(변환이 불가 시, NaN 반환)

- parseInt(String, radix) : 수로 시작하면 숫자 부분만 정수로 변경, 수가 아니면 NaN 반환
  (두 번째 인자로 radix는 2~36까지 전달하여, 전달된 String을 해당 진법으로 해석하고 10진법으로 전환하여 반환)

- parseFloat() : 수로 시작하면 숫자 부분만 실수로 변경, 수가 아니면 NaN 반환
- Number() : Boolean도 숫자로 변경, 숫자로 바꿀 수 없는 문자열/객체는 NaN반환

console.log(Number('1'));        // 1
console.log(Number('abs'));      // NaN
console.log(Number(true));       // 1
console.log(Number([1, 2]));     // NaN
console.log(Number({1 : '1', 2 : '2'})); // NaN
console.log(Number("2021년"));   // NaN

console.log(parseInt('123'));    // 123
console.log(parseInt('10', 2));  // 2 ( 2진법 '10'은 10진법으로 2이다.)
console.log(parseInt('cbd'));    // NaN
console.log(parseInt(true));     // NaN
console.log(parseInt([1, 2]));   // 1
console.log(parseInt({1 : '1', 2 : '2'})); // NaN
console.log(parseInt("2021년")); // 2021

console.log(parseFloat(13));     // 13
console.log(parseFloat('cbd'));  // NaN
console.log(parseFloat(true));   // NaN
console.log(parseFloat([1, 2])); // 1
console.log(parseFloat({1 : '1', 2 : '2'})); // NaN
console.log(parseFloat("21.15%")); // 21.15

 

2) 문자로 변환하는 전역 함수

- String()

console.log(String(123));    // 123
console.log(String(true));   // true
console.log(String([1, 2])); // 1, 2
console.log(String({1 : '1', 2 : '2'})); // [obejct Object]

 


3) Boolean으로 변환하는 전역 함수

- Boolean() : truthy / falsy에 따라서 변환
- truthy : 자바스크립트에서 true로 취급되는 것 → [true, {}, [], 문자열, 정수, 실수]
- falsy : 자바스크립트에서 false로 취급되는 것 → [false, '', null, undefined, 0, -0, NaN]

console.log(Boolean(123));    // true
console.log(Boolean(true));   // true
console.log(Boolean([1, 2])); // true
console.log(Boolean({1 : '1', 2 : '2'})); // true

console.log(Boolean(0));      // false
console.log(Boolean(undefined)); // false
console.log(Boolean(null));   // false
console.log(Boolean(NaN));    // false

 

4) Object로 변환하는 전역 함수

- Object()

console.log(Object(123));    // [Number: 123]
console.log(Object(true));   // [Boolean: true]
console.log(Object([1, 2])); // [1, 2]
console.log(Object({1 : '1', 2 : '2'})); // {'1' : '1', '2' : '2'}

 

 

위 내용이 헷갈리면 아래의 그림을 참고

 

 

추가적으로, Number 객체 내부에는 숫자를 문자로 변환하는 함수를 별도로 제공한다.

1) toExponential(num) : 정수 부분은 1자리, 소수는 입력 수(num)만큼 e표기법 사용해 문자열 변환
2) toFixed(num) : 소수 부분을 입력 받은 수만큼 사용해 숫자를 문자열로 변환
3) toPrecision() : 입력 받은 수만큼 숫자를 문자열 변환(정밀도 나타냄)
4) toString() : 입력 받은 수로 진법 변환하여 나타냄(String객체의 valueOf 함수와 동일)

console.log(Number(123456).toExponential(2)); // 1.23e+5

console.log(Number(123456.657).toFixed(2));  // 123456.66 (반올림)

console.log(Number(123456.567).toPrecision(5)); // 1.2346e+5

console.log(Number(12).toString(2)); // 1100
console.log(Number(12).toString(8)); // 14
console.log(Number(12).toString(16)) // c

 

※ 참고 - toString()과 String()의 차이점
  - null, undefined를 toString()은 변환 불가하지만, String()은 가능하다.

let str = null.toString();
console.log(str, typeof str);  // Error

str = undefined.toString();
console.log(str, typeof str);  // Error

str = String(null);
console.log(str, typeof str);  // null, String

str = String(undefined);
console.log(str, typeof str);  // undefined, String

 

※ 참고2 - parseInt()/parseFloat()과 Number()의 차이점
  - parseInt/parseFloat는 전체 문자열을 파싱하여 숫자를 찾고, Number는 숫자를 생성하는 역할을 한다.
  - 상단에 있는 코드에서도 알 수 있지만 다음과 같은 차이가 있다.

console.log(Number("2021년"));       // NaN
console.log(parseInt("2021년"));     // 2021
console.log(parseInt("제1회"));      // NaN

console.log(parseFloat("21.15%"));   // 2021
console.log(parseFloat("약21.15%")); // NaN

 

 

 

자바스크립트는 toString, parseInt을 쓰는 것보다 String(), Number()를 쓰는 것을 권장한다.

참고로 위의 코드에서 볼 수 있다 싶이, typeof 예약어를 통해 데이터의 타입을 확인할 수 있다.

 

반응형