[JavaScript] 타입 변환 Type conversion
참고 문서
- 자바스크립트 완벽 가이드 (데이비드 플래너건, 인사이트)
- Type conversion - MDN Web Docs Glossary: Definitions of Web-related terms | MDN
- Type coercion - MDN Web Docs Glossary: Definitions of Web-related terms | MDN
개요
자바스크립트의 타입 변환에 대해 정리한 글.
암묵적 타입 변환 Type coercion
Type coercion 또는 implicit(automatic) type conversion이라 한다. 자바스크립트가 필요에 따라 타입 변환을 자동으로 수행하는 것을 말한다. 가령 문자열이 필요한 위치인데 실제 값은 문자열이 아니라면 자바스크립트는 해당 값을 문자열 타입으로 변환하려 한다.
다음은 암묵적 타입 변환의 사례들이다:
if (1) {
console.log('1 is true');
}
if (!'') {
console.log('empty string is false');
}
if ('false') {
console.log('"false" is true');
}
if문의 조건으로 불리언이 아닌 값이 할당되면 이 값은 불리언 타입으로 변환된다.
var a = 1;
a = a + '';
typeof a; // "string"
typeof +a; // "number"
var b = "2";
typeof b++; // "number"
var c = "xxx";
-c; // NaN
c++; // NaN
산술 연산자 +
는 피연산자가 문자열일 때 다른 피연산자를 문자열로 변환한다. +
가 단항 연산자로 사용되면 피연산자를 숫자로 변환한다. 단항 연산자 -
와 증감 연산자 --
, ++
의 암묵적 타입 변환도 동일하게 작동한다. 만약 숫자로 변환할 수 없는 문자열이면 NaN
을 반환한다.
1 == "1"; // "1"은 1로 변환
true == 1; // true는 1로 변환
false == 0; // false는 0으로 변환
"1" == true; // "1"은 true로 변환
['a'] == 'a'; // 객체는 toString()이나 valueOf()를 사용해 문자열로 변환
동등 연산자 ==
는 피연산자들이 서로 타입이 다를 때 타입 변환을 시도한다. 규칙은 다음과 같다:
- 둘 중 하나가 숫자이고 나머지 하나가 문자열일 때 문자열을 숫자로 변환한다.
- 둘 중 하나가 불리언이고 나머지 하나가 숫자일 때 불리언을 숫자로 변환한다.
- 둘 중 하나가 문자열이고 나머지 하나가 불리언일 때 문자열을 불리언으로 변환한다.
- 둘 중 하나가 객체고 나머지 하나가 숫자 또는 문자열이면 객체를 문자열로 변환한다. 이 때 해당 객체의
toString()
이나valueOf()
가 사용된다.
명시적 타입 변환 Type conversion
Boolean('abcd'); // true
String(123); // "123"
String(true); // "true"
Number('123'); // 123
Number('a123'); // NaN
Object(123); // new Number(123)과 같다.
자동으로 수행되는 타입 변환 말고도 명시적인 타입 변환이 필요할 수 있다. 원시 타입으로의 변환을 원할 경우엔 단순히 Boolean()
, Number()
, String()
, Object()
함수를 사용하면 된다.
Boolean({a: 1}); // true, 객체는 모두 true로 변환된다.
객체를 불리언으로 변환할 때는 단 하나의 규칙만 기억하면 된다: 객체는 무조건 true다.
var obj = {a: 1, b: 2};
String(obj); // [object Object]
var arr = [1, 2, 3];
String(arr); // "1,2,3"
function fn() {
console.log('do something');
}
String(fn); // "function fn() { console.log('do something');}"
String(/D/g); // ""/D/g"
String(new Date()); // "Thu Jul 07 2016 15:32:36 GMT+0900"
객체를 문자열로 변환하려고 할 때 객체가 toString()
메서드를 갖고 있다면 자바스크립트는 이 메서드를 호출할 것이다. 만약 toString()
을 갖고 있지 않거나 원시 타입을 반환하지 않으면 toString()
대신 valueOf()
를 찾는다. valueOf()
가 원시 타입을 반환하면 이 값을 문자열로 변환하겠지만 만약 valueOf()
가 없거나 원시 타입을 반환하지 않으면 TypeError가 발생한다.
Number([]); // 0
Number([1]); // 1
Number([1, 2]); // NaN
객체를 숫자로 변환할 땐 문자열과 반대로 valueOf()
를 먼저 찾는다. valueOf()
가 있고 원시 타입을 반환하면 이 값을 숫자로 변환하여 돌려준다. valueOf()
가 없거나 원시 타입을 반환하지 않으면 자바스크립트는 toString()
을 찾으며 같은 작업을 수행한다. 만약 toString()
이 없거나 원시 타입을 반환하지 않으면 TypeError가 발생할 것이다.
"abcdef".valueOf(); // "abcdef"
/D/g.valueOf(); // /D/g
new Date().valueOf(); // 1467874589125, 1970-01-01 부터 지난 시간을 밀리초로 표현한 값
valueOf()
메서드는 오직 래퍼 객체와 정규식, Date 타입에서만 의미 있다. 기본적으로 valueOf()
는 원시 타입으로 변환된 값을 돌려주도록 되어 있는데 대부분의 객체가 원시 타입으로 변환될 수 없으므로 단지 자기 자신(객체 자체)을 돌려줄 뿐이다. 빈 배열이 숫자 0으로 변환되는 것은 이런 특성탓이라 설명할 수 있다.
Array 타입은 valueOf()
대신 toString()
을 호출한다(규칙에 따라 valueOf()
를 먼저 찾았으나 원시 타입이 아닌 객체를 돌려주므로 toString()
을 대신 호출하는 것). toString()
은 빈 배열을 빈 문자열로 돌려주며 빈 문자열을 숫자로 바꾸면 0이 되는 것이다.
자바스크립트 타입 변환 표
String | Number | Boolean | Object | |
---|---|---|---|---|
undefined | "undefined" | NaN | false | TypeError |
null | "null" | 0 | false | TypeError |
true | "true" | 1 | new Boolean(true) | |
false | "false" | 0 | new Boolean(false) | |
"" (empty string) | 0 | false | new String("") | |
"1.2" | 1.2 | true | new String("1.2") | |
"one" | NaN | true | new String("one") | |
" " | 0 | true | new String(" ") | |
123 | "123" | true | new Number(123) | |
-1 | "-1" | true | new Number(-1) | |
0 | "0" | false | new Number(0) | |
-0 | "0" | false | new Number(-0) | |
NaN | "NaN" | false | new Number(NaN) | |
Infinity | "Infinity" | true | new Number(Infinity) | |
-Infinity | "-Infinity" | true | new Number(-Infinity) | |
{ } | true | |||
[ ] | 0 | true | ||
[9] | "9" | 9 | true | |
["a"] | NaN | true | ||
[1, 2] | NaN | true | ||
function () { } | NaN | true |
출처: JavasScript: The Definitive Guide. David Flanagan 저. 6판. 58쪽