개발자가 의도적으로 값의 타입을 변환하는 것을 타입 캐스팅이라고 한다.
개발자의 의도와 상관없이 표현식을 평가하는 도중에 js엔진에 의해 암묵적으로 타입이 자동변환되기도 한다. 이를 암묵적 타입 변환이라고 한다.
'10' + 2 // '102'
5 * '10' // 50
!0 // true
if (1) { }
1 + '2' // "12"
(symbol()) + '' // TypeError
({}) + '' // "[object Object]"
1 - '1' // 0
1 * '10' // 10
1 / 'one' // 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
자바스트립트 엔진은 불리언 타입이 아닌 값을 Truthy값 또는 Falsy값으로 구분한다.
명시적 타입 변환은 크게
으로 나뉜다.
// 1
String(1); // '1'
String(NaN); // 'NaN'
String(false); // 'false'
// 2
(1).toString(); // '1'
(true).toString(); // 'true'
// 3
1 + ''; // '1'
Infinity + ''; // 'Infinity'
// 1
Number('1'); // 1
Number('true'); // 1
// 2
parseInt('0'); // 0
parseInt('false') // 0
// 3
+'2' // 2
+'Hello' // NaN
// 4
'0' * 1; // 0
'Infinity' * 1 // Infinity
// 1
Boolean('x'); // true
Boolean(''); // false
Boolean(0); // false
Boolean(5); // true
Boolean(NaN); // false
Boolean(null); // false
Boolean(undefined); // false
Boolean({}); // true
Boolean([]); // true
// 2
!!('x'); // true
!!(0); // false
!!(null); // false
!!({}); // true
'Cat' && 'Dog' // Dog
'Cat' || 'Dog' // Cat
위의 예제에서 'Cat'과 'Dog'는 모두 Truthy 값이다.
&& 연산자는 좌항이 true 값일 시 우항까지 확인을 해야 최종값이 true인지 아닌지 확인할 수 있다. 즉, 좌항이 true 라면 우항을 반환, 좌항이 false 라면 좌항을 반환한다. || 연산자는 좌항이 true 값일 시 우항의 값과 상관없이 true값을 반환한다. 이러한 특성을 이해하면 단축 평가를 쉽게 이해할 수 있다.
단축평가는 이러할 때 유용하다
객체를 가리키기를 기대하는 변수가 null 또는 undefined가 아닌지 확인하고 프로퍼티를 참조할 때
var elem = null;
// elem이 null이나 undefined와 같은 Falsy 값이면 elem으로 평가되고
// elem이 Truthy 값이면 elem.value로 평가된다.
var value = elem && elem.value; // null
ES11(ECMAScript2020)에서 도입된 null 병합 연산자 ??는 좌항의 피연산자가 null 또는 undefined인 경우 우항의 피연산자를 반환하고, 그렇지 않으면 좌항의 피연산자를 반환한다.
var foo = null ?? 'Hello!'
console.log(foo); // Hello!
ES11(ECMAScript2020)에서 도입된 옵셔널 체이닝 연산자 ?.는 좌항의 피연산자가 null 또는 undefined인 경우 undefined를 반환하고, 그렇지 않으면 우항의 프로퍼티 참조를 이어간다.
var str = '';
// 문자열의 길이(length)를 참조한다. 이때 좌항 피연산자가 false로 평가되는 Falsy 값이라도
// null 또는 undefined가 아니면 우항의 프로퍼티 참조를 이어간다.
var length = str?.length;
console.log(length); // 0