타입 변환은 크게 개발자가 의도적으로 값의 타입을 변환하는 명시적 타입 변환과 자바스크립트 엔진에 의해 암묵적으로 타입을 변환하는 암묵적 타입 변환이 있다.
암묵적 타입 변환
: 코드의 문맥에 부합하지 않을 때 자바스크립트는 에러를 띄우는 것이 아니라 암묵적 타입 변환을 통해 표현식을 평가한다.
'10' + 2 // '102' 5 * '10' // 50 !0 //true if(1) {}
- 문자열 타입으로 변환
이항 연산자 +를 사용할 때 피연산자 중 하나 이상이 문자열이면 문자열 연결 연산자로 동작하여 다른 하나도 문자열로 변환된다.
1 + '2' // '12' '2' + 1 // '21'
→ 문자열 연결 연산자의 역할은 문자열 값을 만드는 것이기 때문!
0 + '' // '0' -0 + '' // '0' 1 + '' // '1' -1 + '' // '-1' true + '' // 'true' false + '' // 'false' null + '' // 'null'
- 숫자 타입으로 변환
: 산술 연산자 -, * / 등을 사용할 경우 모든 피연산자는 숫자 타입으로 변환된다.
1 - '1' //0 1 * '20' //20 1 / 'one' // NaN
→ 산술 연산자의 역할은 숫자 값을 만드는 것이기 때문이다!
하지만 피연산자를 숫자 타입으로 변환할 수 없는 경우 평과 결과는 NaN이 된다.
: 단항 연산자 +는 피연산자가 숫자타입이 아닌 경우 숫자 타입으로 변환하기 때문에 타입 변환이 필요할 때 유용하게 사용할 수 있다.
+'' //0 +'0' //0 +'22'//22 +true //1 +false // 0 +null // 0 +undefined //NaN
: 산술 연산자와 마찬가지로 비교 연산자 역시 모든 피연산자는 숫자 타입으로 변환된다.
'1' > 0 //true '2' === 2 //false '2' == 2 //true '2' < 5 //true
하지만 비교 연산자 중에서 동등 비교 연산자(==)는 암묵적 타입 변환을 통해 타입을 일치시킨 후 값을 비교하지만 일치 비교 연산자(===) 의 경우 타입 변환이 일어나지 않는다.
*이러한 동등 비교 연산자가 편리할 때도 있지만 예기치 않은 결과를 만들어내기도 하므로 일치 비교 연산자를 사용하는 것이 좋다.
명시적 타입 변환
: 개발자가 의도에 따라 명시적으로 타입을 변경하는 방법
- 문자열 타입으로 변환
- String 생성자 함수를 new 연산자 없이 호출
- toString() 메서드를 사용하는 방법
- 문자열 연결 연산자를 이용하는 방법
String(1) //'1' STring(NaN) //'NaN' -------------------- (1).toString(); //'1' (NaN).toString(); //'NaN' -------------------- 1+'' // '1' NaN + '' //'NaN'
- 숫자 타입으로 변환
- Number생성자 함수를 new 연산자 없이 호출
- parseInt. parseFloat 함수를 사용하는 방법(문자열만 가능)
- +단항연산자 이용
- *산술연산자 이용
Number('0') // 0 Number('-1') // -1 Number(true) // 1 ---------------- parseInt('0') //0 parseInt('-1') // -1 ---------------- +'0' //0 +'-1' //-1 +true // 1
- 불리언 타입으로 변환
- Boolean 생성자 함수를 new 연산자 없이 호출
- ! 부정 논리 연산자를 두 번 사용하는 방법
Boolean('x') // true Boolean(0) //false Boolean(1) //true !!'x' //true !!0 //false !!1 //true
단축평가
- 논리 연산자를 사용한 단축 평가
: 논리곱 연사자(&&)는 두 개의 피연산자가 모두 true일 때 true를 반환
'Cat' && 'Dog' // 'Dog'
두 개의 피연산자를 모두 평가해야하므로 두번째 피연산자가 평가결과를 결정
→ 논리곱 연산자는 값이 true 일 때 논리 연산의 결과를 결정하는 두 번째 피연산자를 반환한다.
:논리합 연산자(||)는 두 개의 피연산자 중 하나만 true로 평가되어도 true를 반환한다.
'Cat' || 'Dog' // 'Dog'
하나만 true여도 true이므로 첫번째 피연산자가 평가 결과를 결정
→ 논리합 연산자는 논리 연산의 결과를 결정하는 첫 번째 피연산자를 반환
false || 'Dog' //'Dog' 'Cat' || false //Cat --------------------- false && 'Dog' //false 'Cat' && false //false
- 어떤 조건이 true일 때, 논리곱 연산자는 if문을 대체할 수 있다.
let done = true; let message = ''; //if문을 사용할 때 if(done) mmessage = '완료'; //논리곱 연산자를 사용할 때 message = done && '완료';
- 어떤 조건이 false일 때, 논리합 연산자로 if문을 대체할 수 있다.
let done = false; let message = ''; //if문을 사용할 때 if(!done) mmessage = '미완료'; //논리곱 연산자를 사용할 때 message = done || '미완료';
옵셔널 체이닝 연산자
?. 는 좌항의 피연산자가 null이거나 undefined인 경우 undefined를 반환하고 그렇지 않으면 우항의 프로퍼티 참조를 이어간다.
let elem = null; let value = elem?.value; console.log(value) //undefined
옵셔널 체이닝 연산자가 도입되기 이전에는 논리 연산자를 사용했는데 논리연산자와 옵셔널 체이닝 연산자의 차이점은 좌항 피연산자가 false로 평가될 때이다.
논리연산자의 경우 좌항 피연산자가 false로 평가되면 좌항 피연산자를 그대로 반환한다.
const str = ''; const length = str && str.length; console.log(length);// ''
옵셔널 체이닝 연산자는 좌항 피연산자가 false여도 null이나 undeifined가 아니면 우항의 프로퍼티 참조를 이어간다.
const str = ''; const length = str?.length; console.log(length);// 0
null 병합 연산자
null 병합 연산자 ??는 좌항의 피연산자가 null 또는 undefined인 경우 우항의 피연산자를 반환, 그렇지 않으면 좌항의 피연산자를 반환한다.
const foo = null ?? 'default string'; console.log(foo); // 'default string';
그래서 이러한 null 병합 연산자는 이렇게 변수의 기본값을 설정할 때 유용하다.
null 병합 연산자가 도입되기 이전에는 논리합연산자를 이용했는데 이 둘의 차이점도 좌항의 피연산자가 false일 때 있다.
논리합 연산자의 경우 좌항의 피연산자가 false이면 우항의 피연사자가 반환된다. 이때 만약 변수에 falsy값인 0이나 ””을 넣고싶은 경우 예기치 않은 동작이 발생할 수 있다.
const foo = '' || 'default string'; console.log(foo); // 'default string';
하지만 null 병합 연산자의 경우 좌항의 피연산자가 false여도 null이나 undeifined가 아니면 좌항의 피연산자를 반환한다.
const foo = '' ?? 'default string'; console.log(foo); // ''