개발자의 의도에 따라 다른 타입으로 변환하는 것을 명시적 타입변환(타입 캐스팅)이라고 한다
하지만 JS엔진은 개발자의 의도와는 상관없이 타입을 강제로 변환하는데 이를 암묵적 타입변환(타입 강제 변환)이라고 한다
타입 변환이란 기존 원시값을 사용해 다른 타입의 새로운 원시값을 생성하는 것이다.
JS엔진은 표현식의 에러 없이 평가 하기 위해서 암묵적 타입변환을 통해 새로운 타입의 값을 만들어 단 한 번 사용하고 버린다.
이런 방식은 예측하기 어려워 오류를 생산할 수 있지만 규칙이 있고 훨신 편리하게 사용할 수 있으니 암묵적 타입변환의 규칙을 익혀놔야한다.
암묵적 타입변환에서 헷갈리는 것들만 정리하자면
문자열 타입
숫자 타입
객체와 빈배열이 아닌 배열, undefined는 숫자로 타입강제변환이 되지않아 NaN으로 표기된다.
불리언 타입
불리언 값이 들어가야 하는 곳에 다른 타입이 들어온다면 JS엔진은 불리언 타입이 아닌 값을 Truthy값(참으로 평가되는 값) / Falsy 값(거짓으로 평가되는 값)으로 구분한다.
이때 Falsy로 평가되는 값은 false, undefined, null, 0, -0, NaN, ‘’ 가 있고 나머지는 모두 Truthy 값으로 평가된다.
명시적 타입변환 방법은 여러가지가 있는데 표준 빌프인 생성자 함수(String, Number, Boolean)를 사용하는 방법과 빌트인 메서드를 사용하는 방법, 암묵적 타입변환을 응용하는 방법이 있다.
단축 평가는 표현식을 평가하는 도중에 평가 결과가 확정난 경우 나머지 평가 결과를 생략하는 방식이다.
논리 연산자를 사용한 단축 평가
&&, ||를 사용하면 피연산자 중 어느 한쪽으로 평가되는데 이를 통해서 단축 평가를 할 수가 있다.
단축 평가를 통해 논리 연산의 결과를 결정하는 피연산자를 반환하는데
&&를 사용하면 두번째 피연산자의 값을 그대로 반환한다
|| 를 사용하면 첫번째 피연산자의 값을 그대로 반환한다
// 논리합(||) 연산자
'Cat' || 'Dog' // -> "Cat"
false || 'Dog' // -> "Dog"
'Cat' || false // -> "Cat"
// 논리곱(&&) 연산자
'Cat' && 'Dog' // -> "Dog"
false && 'Dog' // -> false
'Cat' && false // -> false
이처럼 논리 연산의 결과를 결정하는 피연산자를 타입 변환하지 않고 그대로 반환는데 이러한 단축 평가로 효율을 높인다.
이를 통해 if문 대신 사용할 수 있다.
var done = true;
var message = '';
// 주어진 조건이 true일 때
if (done) message = '완료';
// if 문은 단축 평가로 대체 가능하다.
// done이 true라면 message에 '완료'를 할당
message = done && '완료';
console.log(message); // 완료
// 주어진 조건이 false일 때
if (!done) message = '미완료';
// if 문은 단축 평가로 대체 가능하다.
// done이 false라면 message에 '미완료'를 할당
message = done || '미완료';
console.log(message); // 미완료
다른 활용법으로는 null, undefined로 인해 타입에러가 나오는 것을 막을 수있다.
var elem = null;
var value1 = elem.value; // TypeError: Cannot read property 'value' of null
// elem이 null이나 undefined와 같은 Falsy 값이면 elem으로 평가되고
// elem이 Truthy 값이면 elem.value로 평가된다.
var value2 = elem && elem.value; // -> null
비슷한 예시로 매개변수에 기본값을 설정할 때도 사용할 수있지만 ES6부터 기본값을 설정할 수 있기 때문에 굳이 안쓸듯
옵셔널 체이닝(?.) 연산자 (ES11~)
?.는 좌항의 피연산자가 null이나 undefined인 경우 undefined를 반환하고 그렇지 않으면 . 으로 프로퍼티 참조를 이어간다
var elem = null;
var value = elem?.value;
console.log(value); // undefined
논리 연산자 &&도 비슷하게 쓸 수 있지만 &&는 Falsy값(false, undefined, null, 0, -1, NaN, ‘’) 모두 좌항의 피연산자를 그대로 반환하지만 ?.를 사용하면 null과 undefined 가 아니면 우항으로 평가한다
var str = '';
// 문자열의 길이(length)를 참조한다.
var length = str && str.length;
// 문자열의 길이(length)를 참조하지 못한다.
console.log(length); // ''
// 문자열의 길이(length)를 참조한다. 이때 좌항 피연산자가 false로 평가되는 Falsy 값이라도
// null 또는 undefined가 아니면 우항의 프로퍼티 참조를 이어간다.
var length = str?.length;
console.log(length); // 0
Null 병합(??) 연산자 (ES11~)
??는 좌항의 피연산자가 null 또는 undefined인 경우에 우항의 피연산자를 반환하고 그렇지 않은면 좌항의 피연산자를 반환한다
|| 와 비슷하게 사용할 수 있지만 옵셔널 체이닝 연산자와 &&의 차이와 비슷하게
||는 Falsy값(false, undefined, null, 0, -1, NaN, ‘’) 모두 우항의 피연산자를 그대로 반환하지만 ??를 사용하면 null과 undefined 가 아니면 좌항으로 평가한다
// Falsy 값인 0이나 ''도 기본값으로서 유효하다면 예기치 않은 동작이 발생할 수 있다.
var foo = '' || 'default string';
console.log(foo); // "default string"
// 좌항의 피연산자가 Falsy 값이라도 null 또는 undefined가 아니면 좌항의 피연산자를 반환한다.
var foo = '' ?? 'default string';
console.log(foo); // ""