타입 변환에는 크게 2가지가 있다.
JS 엔진이 값이 쓰이는 상황에 따라 타입 변환을 하는 암묵적 타입 변환
개발자가 의도적으로 타입 변환을 하는 명시적 타입 변환
var str = 1 + '2';
console.log(str); // '12'
위의 예시에서 str
을 출력해보면 '12'
로 문자열 타입으로 출력된다.
분명 숫자 1
과 문자열 2
를 더했으나, JS 엔진은 +
기호를 문자열 연결 연산자로 해석해 숫자 1
을 문자열 1
로 암묵적인 타입 변환을 해 연산한 것이다.
암묵적인 타입 변환의 대표적인 예시들을 알아보자.
+
기호를 제외한 나머지 산술 연산자는 숫자를 계산하기 위해 사용하는 연산자이므로 피연산자는 숫자 타입이어야 한다. 따라서 JS 엔진은 숫자 타입으로 암묵적 변환을 한다.
만약 숫자로 변환이 어려운 피연산자는 계산을 할 수 없으므로 표현식의 결과가 NaN
이 된다.
1 - '1'; // 0
1 * '10'; // 10
1 / ''; // Infinity
1 / 'hi'; // NaN
숫자와 비교하는 표현식 역시 문자역 1
을 숫자로 타입 변환을 해 비교한다.
'1' > 0; // true
+ 단항 연산자
를 숫자가 아닌 피연산자 앞에 붙이면 해당 피연산자를 숫자 타입으로 변환한다.
+'1'; // 1
+''; // 0
+'hi'; // NaN
+null; // 0
+undefined; // NaN
+true; // 1
+false; // 0
+Symbol(); // TypeError
+{}; // NaN
+[]; // 0
+[10, 20]; // NaN
+(function(){}); // NaN
위에서 언급했듯, +
연산자가 하나 이상의 문자열이 있는 표현식에 사용되면 문자열 연결 연산자
로 사용된다. 이 때, 문자열 타입으로 피연산자를 변환한다.
1 + ''; // '1'
NaN + ''; // 'NaN'
Infinity + ''; // 'Infinity'
-11 + ''; // '-11'
true + ''; // 'true'
false + ''; // 'false'
null + ''; // 'null'
undefined + ''; // 'undefined'
(Symbol()) + ''; // TypeError
({}) + ''; // '[obejct Object]'
[] + ''; // ''
[1, 2] + ''; // '1, 2'
(function(){}) + ''; // 'function(){}'
Array + ''; // 'function Array() { [native code] }'
if문이나 삼항 조건 연산자와 같은 조건식이 필요한 표현식은 true/false 값이 필요하다.
JS 엔진은 조건식에 true/false가 아닌 값이 있을 경우 Truthy 값(참으로 평가되는 값)
Falsy 값(거짓으로 평가되는 값)
으로 판단할 수 있도록 암묵적인 타입 변환을 한다.
특히 Falsy
로 판단되는 값들을 기억하면 좋다.
// Truthy
if (1) ~
if ('hi') ~
// Falsy
if (undefined) ~
if (null) ~
if (0) ~
if (NaN) ~
if ('') ~
이러한 불리언으로 암묵적인 타입 변환을 하는 대표적인 예시가 짝수, 홀수를 판단할 때이다. 만약 짝수이면 2로 나눈 나머지가 항상 0 이므로 Falsy 값으로 타입 변환된다.
var x = 2;
if (x % 2) console.log(`${x}는 홀수`);
else console.log(`${x}는 짝수`); // 2는 짝수
개발자가 의도적으로 타입 변환을 하기 위해 명시적인 타입 변환을 만드는 방법 3가지가 있다.
String
생성자 함수를 사용하기Object.prototype.toString()
메서드 사용하기문자열 연결 연산자
사용하기String(1); // '1'
String(Infinity); // 'Infinity'
String(true); // 'true'
(11).toString(); // '11'
(false).toString(); // 'false'
1 + ''; // '1'
NaN + ''; // 'NaN'
true + ''; // 'true'
Number
생성자 함수 사용하기parseInt
, parseFloat
함수 사용하기 (단, 문자열만 숫자 타입으로 변환 가능)+
단항 연산자 사용하기Number('123'); // 123
Number('NaN'); // NaN
Number(true); // 1
parseInt('-1'); // -1
parseInt('-1.1'); // -1
parseFloat('12.12'); // 12.12
+'0'; // 0
+'NaN'; // NaN
+true; // 1
+null; // 0
'1' * 10; // 10
false * 1; // 0
Boolean
생성자 함수 사용하기!!
부정 논리 연산자 사용하기Boolean('hi'); // true
Boolean(0); // false
Boolean(null); // false
Boolean(undefined); // false
Boolean(''); // false
Boolean({}); // true
Boolean([]); // true
!!'x'; // true
!!''; // false
!!1; // true
!!NaN; // false
!!null; // false
!!undefined; // false
!!{}; // true
!![]; // true
단축 평가는 논리 합(||), 논리 곱(&&)으로 이루어진 표현식에서 평가 결과가 논리적인 참/거짓 값으로 확정되어 이후 평가를 생략하는 것을 의미한다.
또한 피연산자가 타입 변환되지 않고 원래 값대로 반환되기 때문에 피연산자 둘 중 하나의 값으로 평가된다.
단축 평가 규칙
true
|| anything
=> true
false
|| anything
=> anything
true
&& anything
=> anything
false
&& anything
=> false
논리 합의 경우 OR 연산이므로 피연산자 둘 중 하나만 true로 평가되어도 true를 반환한다.
즉, 첫번째 피연산자가 true이면 두번째 피연산자를 확인할 필요가 없으므로 첫번째 피연산자를 반환한다.
'Cat' || 'Dog'; // 'Cat'
논리 곱의 경우 AND 연산이므로 피연산자 모두 true로 평가되어야 true를 반환한다.
즉, 첫번째 피연산자가 true이면 두번째 피연산자의 값에 따라 결과가 평가되므로 두번째 피연산자의 값이 반환된다.
'Cat' && 'Dog'; // 'Dog'
만약 car
라는 변수에 number
라는 프로퍼티 값을 참조하기 위해서는 먼저 car
가 가리키는 주소의 값에는 객체가 존재해야 한다.
car
값이 null
또는 undefined
이면 단축 평가를 통해 논리 곱 연산자 뒤의 프로퍼티를 참조하지 않는다.
즉, null
또는 undefined
값이 반환되므로 프로퍼티를 참조하지 못하는 타입 에러를 방지할 수 있다.
var car = null;
var carNumber = car.number; // TypeError
var carNumber = car && car.number; // null
함수를 호출할 때 매개변수에 어떤 값도 전달하지 않으면 undefined
가 매개변수에 할당된다.
undefined
가 할당됨에 따라 발생할 수 있는 에러를 해결하기 위해 단축 평가를 사용할 수 있다.
function getStringLength(str) {
str = str || '';
return str.length;
}
getStringLength(); // 0
getStringLength('hi'); // 2
// ES6 매개변수 기본값 설정
function getStringLength(str = '') {
return str.length;
}
ES11부터 옵셔널 체이닝 연산자 ?.
을 피연산자 뒤에 사용하면 피연산자가 null
이나 undefined
일 경우 연산자 뒤의 프로퍼티를 참조하지 않고 undefined
를 반환한다.
var car = null;
var carNumber = car?.number; // undefined
위에서 설명한 논리 곱 &&
를 객체의 프로퍼티를 참조하는 것과 다른 점은 연산자 앞 피연산자가 falsy
값일 경우 해당 값을 그대로 반환하지만 ?.
는 피연산자 falsy
값이여도 null
이나 undefined
인 경우가 아니면 프로퍼티를 참조한다.
var str = '';
var length = str && str.length; // ''
var length = str?.length; // 0
ES11부터 null 병합 연산자 ??
를 사용할 수 있다. 연산자 앞의 피연산자가 null
이나 undefined
이면 뒤의 피연산자가 반환되고, 아니면 앞의 피연산자가 반환된다.
var value = null ?? 'default value'; // default value
논리 합 ||
과 다른 점은 논리 합 연산자 앞의 피연산자 값이 falsy
이면 뒤의 피연산자 값이 반환되는 반면 ??
연산자는 앞의 피연산자가 null
이나 undefined
가 아닌 falsy
값이면 앞의 피연산자를 그대로 반환한다.
var str = '';
var value = str ?? 'default value'; // ''
주의할 점은 0
이나 ''
같은 값이 유효한 값으로 여길 경우 논리 합 ||
을 사용할 때 문제가 발생할 수 있다.