명시적 타입 변환 방법에는 표준 빌트인 생성자 함수(String, Number, Boolean)를 new 연산자 없이 호출하는 방법과 빌트인 메서드(Built-in Method)를 사용하는 방법, 그리고 암묵적 타입 변환을 이용하는 방법이 있다.
표준 빌트인 생성자 함수와 표준 빌트인 메서드는 자바 스트립트에서 기존 제공하는 함수다. 표준 빌트인 생성자 함수는 객체를 생성하기 위한 함수이며 new 연산자와 함께 호출한다. 표준 빌트인 메서드는 자바스트립트에서 기본 제공하는 빌트인 객체의 메서드다.
문자열로 변환하는 방법
1. String 생성자 함수를 new 연산자 없이 호출
2. Object.prototype.toString() 메서드를 사용하는 방법
3. 문자열 연결 연산자(+)를 이용하는 방법
// 1.
String(1); // "1"
String(NaN); // "NaN"
String(Infinity); // "Infinity"
String(true); // "true"
String(false); // "false"
// 2.
(1).toString(); // "1"
(NaN).toString(); // "NaN"
(Infinity).toString(); // "Infinity"
(true).toString(); // "true"
(false).toString(); // "false"
// 3.
1 + ''; // "1"
NaN + ''; // "NaN"
Infinity + ''; // "Infinity"
true + ''; // "true"
false + ''; // "false"
숫자로 변환하는 방법
1. Number 생성자 함수를 new 연산자 없이 호출
2. parseInt, parseFloat 함수를 사용하는 방법(문자열만 숫자 타입으로 변환 가능)
3. + 단항 산술 연산자를 이용하는 방법
4. * 산술 연산자를 이용하는 방법
// 1.
Number('0'); // 0
Number('-1'); // -1
Number('10.53'); // 10.53
Number(true); // 1
Number(false); // 0
// 2.
parseInt('0'); // 0
parseInt('-1'); // -1
parseFloat('10.53'); // 10.53
// 3.
+'0'; // 0
+'-1'; // -1
+'10.53'; // 10.53
+true; // 1
+false; // 0
// 4.
'0' * 1; // 0
'-1' * 1; // -1
'10.53' * 1; // 10.53
true * 1; // 1
false * 1; // 0
문자열로 변환하는 방법
1. Boolean 생성자 함수를 new 연산자 없이 호출
2. ! 부정 논리 연산자를 두 번 사용하는 방법
// 1.
Boolean('x'); // true
Boolean(''); // false
Boolean('false'); // true
Boolean(0); // false
Boolean(1); // true
Boolean(NaN); // false
Boolean(Infinity); /// true
Boolean(null); // false
Boolean(undefined); // false
Boolean({}); // true
Boolean([]); // true
// 2.
!!'x'; // true
!!''; // false
!!'false'; // true
!!0; // false
!!1; // true
!!NaN; // false
!!Infinity; // true
!!null; // false
!!undefined; // false
!!{}; // true
!![]; // true
// 피연산자가 모두 문자열 타입이어야 하는 문맥
'10' + 2 // '102'
// 피연산자가 모두 숫자 타입이어야 하는 문맥
5 * '10 // 50
// 피연산자 또는 표현식이 불리언 타입이어야 하는 문맥
!0 // true
if (1) {}
자바스트립트 엔진은 표현식을 평가할 때 개발자의 의도와는 상관 없이 코드의 문맥을 고려해 암묵적으로 데티어 타입을 강제 변환(암묵적 타입 변환) 할 때가 있다.
암묵적 타입 변환이 발생하면 문자열, 숫자, 불리언과 같은 원시 타입 중 하나로 타입을 자동 변환한다.
// 기본 예시
1 + '2' // "12"
`1 + 1 = ${1 + 1}` // "1 + 1 = 2", 템플릿 리터럴의 암묵적 타입 변환
// 숫자 타입
0 + '' // "0"
-0 + '' // "0"
1 + '' // "1"
-1 + '' // "-1"
NaN + '' // "NaN"
Infinity + '' // "Infinity"
-Infinity + '' // "-Infinity"
// 불리언 타입
true + '' // "true"
false + '' // "false"
// null 타입
null + '' // "null"
// undefined 타입
undefined + '' // "undefined"
// 심벌 타입
(Symbol()) + '' // TypeError: Cannot convert a Symbol value to a string
// 객체 타입
({}) + '' // "[object Object]"
Math + '' // "[object Math]"
[] + '' // ""
[10, 20] + '' // "10,20"
(function(){}) + '' // "function(){}"
Array + '' // "function Array() { [native code] }"
// 기본 예시
1 - '1' // 0
1 * '10' // 10
1 / 'one' // NaN
'1' > 0 // true
// 문자열 타입
+'' // 0
+'0' // 0
+'1' // 1
+'string' // NaN
// 불리언 타입
+true // 1
+false // 0
// null 타입
+null // 0
// undefined 타입
+undefined // NaN
// 심벌 타입
+Symbol() // TypeError: Cannot convert a Symbol value to a number
// 객체 타입
+{} // NaN
+[] // 0
+[10, 20] // NaN
+(function(){}) // NaN
빈 문자열(''), 빈 배열([]), null, false는 0으로, true는 1로 변환된다. 객체와 빈 배열이 아닌 배열, undefined는 변환되지 않아 NaN이 된다는 것에 주의해야 한다
// 기본 예제
if ('') console.log('1');
if (true) console.log('2');
if (0) console.log('3');
if ('str') console.log('4');
if (null) console.log('5');
// 2 4
if문이나 for문과 같은 제어문 또는 삼항 조건 연산자의 조건식은 불리언 값으로 평가 되어야 하는 표현식이다. 자바스크립트 엔진은 조건식의 평가 결과를 불리언 타입으로 암묵적 타입 변환한다.
이 때 자바스크립트 엔진은 불리언 타입이 아닌 값을 Truthy 값(참으로 평가되는 값) 또는 Falsy 값(거짓으로 평가되는 값)으로 구분한다.
// 전달받은 인수가 Falsy 값이면 true, Truthy 값이면 false를 반환한다.
function isFalsy(v) {
return !v;
}
// 전달받은 인수가 Truthy 값이면 true, Falsy 값이면 false를 반환한다.
function isTruthy(v) {
return !!v;
}
논리 연산자를 사용할 때 논리합(||) 또는 논리곱(&&) 연산자 표현식의 평가 결과는 불리언 값이 아닐 수도 있으며, 언제나 2개의 피연산자 중 어느 한쪽으로 평가된다.
'Cat' && 'Dog' // "Dog"
'Cat' || 'Dog' // "Cat"
첫 번째 피연산자인 'Cat'이 Truthy 값이므로 평가 결과 true가 되고, 두 번째 피연산자 'Dog'을 평가해야 한 뒤 논리곱의 평가 결과가 결정된다.
이 때 논리곱 연산자는 논리 연산의 결과를 결정하는 두 번째 피연산자, 즉 문자열 'Dog'를 그대로 반환한다. (논리합 연산자도 동일. 평가 결과를 결정하는 첫 번째 연산자 'Cat'을 그대로 반환)
이처럼 논리 연산의 결과를 결정하는 피연산자를 타입 변환하지 않고 그대로 반환하는 것을 단축 평가(short-circuit evaluation)라 한다. 단축 평가는 표현식을 평가하는 도중에 평가 결과가 확정된 경우 나머지 평가 과정을 생략하는 것을 말한다.
// 논리합(||) 연산자
'Cat' || 'Dog' // "Cat"
false || 'Dog' // "Dog"
'Cat' || false // "Cat"
// 논리곱(&&) 연산자
'Cat' && 'Dog' // "Dog"
false && 'Dog' // false
'Cat' && false // false
단축 평가를 사용하면 if문을 대체할 수 있다. 어떤 조건이 Truthy 값일 때 코드를 실행하려면 논리곱(&&) 연산자를, Falsy일 때 코드를 실행하려면 논리합(||) 연산자를 사용하면 된다.
// if (true)일 때
var done = true;
var message = '';
if (done) message = '완료';
// Truthy 값, && 사용할 때
message = done && '완료';
console.log(message); // "완료"
// if (false)일 때
var done = false;
var message = '';
if (!done) message = '미완료';
// Falsy 값, || 사용할 때
message = done || '미완료';
console.log(message); // "미완료"
객체는 키(key)와 값(value)으로 구성된 프로퍼티(property)의 집합이다. 프로퍼티 참조 시 변수의 값이 null 또는 undefined인 경우 타입 에러(Type Error)가 발생하고, 프로그램이 강제 종료되는데, 단축 평가를 사용해 이를 방지할 수 있다.
// Error case
var elem = null;
var value = elem.value; // TypeError: Cannot read property 'value' of null
// Short-circuit Evaluation
var elem = null;
var value = elem && elem.value; // null
함수를 호출할 때 인수를 전달하지 않으면 매개변수에는 undefined가 할당된다. 이 때 단축 평가를 사용해 매개변수의 기본값을 설정하면 undefined로 인해 발생할 수 있는 에러를 방지할 수 있다.
// 단축 평가를 사용한 매개변수의 기본값 설정
function getStringLength(str) {
str = str || '';
return str.length;
}
getStringLength(); // 0
getStringLength('hi'); // 2
// ES6의 매개변수의 기본값 설정
function getStringLength(str = '') {
return str.length
}
getStringLength(); // 0
getStringLength('hi'); // 2
ES11(ECMAScript2020)에서 도입된 옵셔널 체이닝 연산자 ?. 는 좌항의 피연산자가 null 또는 undefined인 경우 undefined를 반환하고, 그렇지 않으면 우항의 프로퍼티 참조를 이어간다.
var elem = null;
var value = elem?.value;
console.log(value); // undefined
논리곱, 논리합 연산자 사용과의 차이점은 옵셔널 체이닝 연산자는 null, undefined를 제외한 Falsy 값에도 우항의 프로퍼티를 참조한다는 점이다.
ES11(ECMAScript2020)에서 도입된 null 병합 연산자 ?? 는 좌항의 피연산자가 null 또는 undefined인 경우 우항의 피연산자를 반환하고, 그렇지 않으면 좌항의 피연산자를 반환한다. null 병합 연산자는 변수에 기본값을 설정할 때 유용하다.
var foo = null ?? 'default string';
console.log(foo); // 'default string'
논리곱, 논리합 연산자 사용과의 차이점은 마찬가지로 null 병합 연산자는 null, undefined를 제외한 Falsy 값에도 우항의 피연산자를 반환한다는 점이다.