자바스크립트 형 변환
자바스크립트는 타입 검사가 매우 유연해서, 변수의 타입이 정해져 있지 않고 대입 시마다 계속 변한다.
즉, 같은 변수에 다른 타입의 데이터를 계속 새로 할당할 수 있다.
① 묵시적(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 예약어를 통해 데이터의 타입을 확인할 수 있다.
'웹 개발 > JavaScript(+Node, React...)' 카테고리의 다른 글
자바스크립트 - 변수, Scope (0) | 2021.07.25 |
---|---|
자바스크립트 - 데이터 타입 (0) | 2021.07.23 |
자바스크립트(JavaScript) 란? (0) | 2021.07.20 |