
9.1 타입 변환이란?
- 원시 값은 변경 불가능한 값이므로 변경할 수 없지만 타입 변환을 통해 기존 원시 값을 사용해 다른 타입의 새로운 원시값을 생성한다.
// 예제 9-01
var x = 10;
// 명시적 타입 변환
// 숫자를 문자열로 타입 캐스팅한다
var str = x.toString();
console.log(typeof str, str); // string 10
// x변수의 값이 변경된 것은 아니다.
console.log(typeof x, x); // number 10
• 개발자가 의도적으로 값의 타입을 변환하는 것 : 명시적 타입 변환 또는 타입 캐스팅.
// 예제 9-02
var x = 10;
// 암묵적 타입 변환
// 문자열 연결 연산자는 숫자 타입 x의 값을 바탕으로 새로운 문자열을 생성
var str = x + '';
console.log(typeof str, str); // string 10
// x변수의 값이 변경된 것은 아니다.
console.log(typeof x, x); // number 10
• 개발자의 의도와는 상관없이 암묵적으로 값의 타입을 변환하는 것 : 암묵적 타입 변환 또는 타입 강제 변환.
- 기존 변수 값을 재할당하여 변경하는 것이 아닌 표현식을 에러 없이 평가하기 위해 피연산자의 값을 암묵적 타입 변환해 새로운 타입의 값을 만들어 한번 사용하고 버림.
9.2 암묵적 타입 변환
// 예제 9-03
// 피연산자가 모두 문자열 타입이어야 하는 문맥
'10' + 2 // '102'
// 피연산자가 모두 숫자 타입이어야 하는 문맥
5 * '10' // 50
// 피연산자 또는 표현식이 불리언 타입이어야 하는 문맥
!0 // true
if (1) { }
- 표현식을 평가할 때 코드의 문맥에 부합되지 않는 상황이 발생할 수 있다.
- 자바스크립트는 가급적 에러를 발생하지 않도록 암묵적 타입을 통해 표현식을 평가한다.
9.2.1 문자열 타입으로 변환
// 예제 9-04
1 + '2'; // "12"
- + 연산자의 피연산자 중 하나 이상이 문자열이므로 문자열 연산자로 동작.
- 문맥상 모든 피연산자는 코드의 문맥상 모두 문자열 타입이어야 하지만 자바스크립트 엔진은 문자열 타입이 아닌 피연산자를 문자열 타입으로 암묵적 타입 변환한다.
// 예제 9-05
`1 + 1 = ${1 + 1}` // "1 + 1 = 2"
- ES6에서 도입된 템플릿 리터럴의 표현식 삽입은 평과 결과를 문자열 타입으로 암묵적 타입 변환함.
// 예제 9-06
// 숫자 타입
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] }"
9.2.2 숫자 타입으로 변환
// 예제 9-07
1 - '1' // 0
1 * '10' // 10
1 / 'one' // NaN
- 산술 연산자의 모든 피연사자는 코드 문맥상 모두 숫자 타입이여야 한다.
- 피연산자를 숫자 타입으로 변활할 수 없는 경우는 산술 연산을 수행할 수 없으므로 표현식의 평가 결과는 NaN이 됨.
// 예제 9-08
'1' > 0 // true
- > 비교 연산자는 피연산자의 크기를 비교하므로 모든 피연산자는 코드의 문맥상 모두 숫자 타입이어야 함.
- 자바스크립트 엔진은 숫자 타입이 아닌 피연산자를 숫자 타입으로 암묵적 타입 변환함.
// 예제 9-09
// 문자열 타입
+'' // 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
9.2.3 불리언 타입으로 변환
// 예제 9-11
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값(거짓으로 평가되는 값)으로 구분.
- false로 평가되는 Falsy값. 외에 모든 값은 모두 true로 평가되는 Truthy 값이다.
~ false
~ undefined
~ null
~ 0, -0
~ NaN
~ ' '(빈문자열)
// 예제 9-13
// 전달받은 인수가 Falsy 값이면 true, Truthy 값이면 false를 반환
function isFalsy(v){
return !v;
}
// 전달받은 인수가 Truthy 값이면 true, Falsy 값이면 false를 반환
function isTruthy(v){
return !!v;
}
// 모두 true를 반환
isFalsy(false);
isFalsy(undefined);
isFalsy(null);
isFalsy(0);
isFalsy(NaN);
isFalsy('');
// 모두 true를 반환
isTruthy(true);
isTruthy('0'); // 빈 문자열이 아닌 문자열은 Truthy값
isTruthy({});
isTruthy([]);
9.3 명시적 타입 변환
표준 빌트인 생성자 함수와 빌트인 메서드
- 표준 빌트인 생성자 함수 : 객체를 생성하기 위한 함수. new연산자와 함께 호출
- 표준 빌트인 메서드 : 자바스크립트에서 기본 제공하는 빌트인 객체 메서드
9.3.1 문자열 타입으로 변환
// 예제 9-14
// 1. String 생성자 함수를 new 연산자 없이 호출하는 방법
// 숫자타입 -> 문자열 타입
String(1); // "1"
String(NaN); // "NaN"
String(Infinity); // "Infinity"
// 불리언 타입 -> 문자열 타입
String(true);
String(false);
// 2. Object.prototype.toString 메서드를 사용하는 방법
// 숫자타입 -> 문자열 타입
(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"
9.3.2 숫자 타입으로 변환
// 예제 9-15
// 1. Number 생성자 함수를 new 연산자 없이 호출하는 방법
// 문자열 타입 -> 숫자 타입
Number('0'); // 0
Number('-1'); // -1
Number('10.53'); // 10.53
// 불리언 타입 -> 숫자 타입
Number(true); // 1
Number(false); // 0
// 2. parseInt, parseFloat 함수를 사용하는 방법(문자열만 변환 가능)
// 문자열 타입 -> 숫자 타입
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
9.3.3 불리언 타입으로 변환
// 예제 9-16
// 1. Boolean 생성자 함수를 new 연산자 없이 호출하는 방법
// 문자열 타입 -> 불리언 타입
Boolean('x'); // true
Boolean(''); // false
Boolean('false'); // true
// 숫자 타입 -> 불리언 타입
Boolean(0); // false
Boolean(1); // true
Boolean(NaN); // false
Boolean(Infinity); // true
// null 타입 -> 불리언 타입
Boolean(null); // false
// null 타입 -> 불리언 타입
Boolean(undefined); // false
// 객체 타입 -> 불리언 타입
Boolean({}); // true
Boolean([]); // true
// 2. ! 부정 논리 연산자를 두 번 사용하는 방법
// 문자열 타입 -> 불리언 타입
!!'x'; // true
!!''; // false
!!'false'; // true
// 숫자 타입 -> 불리언 타입
!!0; // false
!!1; // true
!!NaN; // false
!!Infinity; // true
// null 타입 -> 불리언 타입
!!null; // false
// null 타입 -> 불리언 타입
!!undefined; // false
// 객체 타입 -> 불리언 타입
!!{}; // true
!![]; // true
9.4 단축 평가
| 단축 평가 표현식 | 평가 결과 |
| true || anything | true |
| false || anything | anything |
| true && anything | anything |
| false && anything | false |
• 단축 평가 : 논리 연산의 결과를 결정하는 피연산자를 타입 변환하지 않고 그대로 반환함.
// 예제 9-20
var done = true;
var message = '';
// 주어진 조건이 true일 때
if (done) message = '완료';
// if문은 단축 평가로 대체 가능하다.
// done이 true라면 message에 '완료'를 할당
message = done && '완료';
console.log(message); // 완료
// 예제 9-21
var done = false;
var message = '';
// 주어진 조건이 false일 때
if (!done) message = '미완료';
// if문은 단축 평가로 대체 가능하다.
// done이 false라면 message에 '미완료'를 할당
message = done || '미완료';
console.log(message); // 미완료
아래와 같이 표현가능하다.
// 예제 9-22
var done = true;
var message = '';
// if ... else 문
if (done) message = '완료';
else message = '미완료';
console.log(message); // 완료
// if ... else 문은 삼항 조건 연산자로 대체 가능하다.
// done이 true라면 message에 '완료'를 할당
message = done ? '완료' : '미완료';
console.log(message); // 완료
객체를 가리키기를 기대하는 변수가 null 또는 undefined가 아닌지 확인하고 프로퍼티를 참조할 때
// 예제 9-24
var elem = null;
// elem이 null이나 undefined와 같은 Falsy 값이면 elem으로 평가되고
// elem이 Trythy 값이면 elem.value로 평가된다.
var value = elem && elem.value; // null
• 객체 : 키와 값으로 구성된 프로퍼티의 집합
- 객체의 변수 값이 객체가 아니라 null 또는 undefined인 경우 객체의 프로퍼티를 참조하면 타입 에러가 발생하지만 단축평가를 사용하면 에러를 발생시키지 않는다.
함수 매개변수에 기본값을 설정할 때
// 예제 9-25
// 단축평가를 사용한 매개변수의 기본값 설정
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
- 함수를 호출할 때 인수를 전달하지 않으면 매개변수에 undefined가 할당되지만 단축평가를 사용해 매개변수의 기본값을 설정하면 에러를 방지할 수 있다.
9.4.2 옵셔널 체이닝 연산자
// 예제 9-26
var elem = null;
// elem이 null 또는 undefined이면 undefined를 반환하고 그렇지 않으면 우항의 프로퍼티 참조를 이어감
var value = elem?.value;
console.log(value); // undefined
• 옵셔널 체이닝 연산자 : ES11에서 도입됨. 연산자 ?.는 좌항의 피연산자가 null 또는 undefined인 경우 undefined을 반환하고 그렇지 않으면 우항의 프로퍼티 참조를 이어감.
// 예제 9-27
var elem = null;
// elem이 Falsy이면 elem으로 평가되고 elem이 Truthy 값이면 elem.value로 평가됨
var value = elem && elem.value;
console.log(value); // null
- 옵셔널 체이닝 연산자가 도입되기 전에 논리 연산자 &&를 사용하여 확인했다.
// 예제 9-28
var str = '';
// 문자열의 길이(length)를 참조한다.
var length = str && str.length;
// 문자열의 길이(length)를 참조하지 못한다.
console.log(length); // ''
- 논리 연산자 &&는 좌항 피연산자가 false로 평가되는 Falsy값이면 좌항 피연산자를 그대로 반환함. 하지만 ' '은 객체로 평가될 때가 있다.
// 예제 9-29
var str = '';
// 문자열의 길이(length)를 참조한다. 이때 좌항 피연산자가 false로 평가되는 Falsy 값이라도
// null 또는 undefined가 아니면 우항의 프로퍼티 참조를 이어간다.
var length = str?.length;
console.log(length); // 0
- 옵셔널 체이닝 연산자는 좌항 피연산자가 false로 평가되는 Falsy값이라도 null 또는 undefined가 아니면 우항의 프로퍼티 참조를 이어감.
9.4.3 null 병합 연산자
// 예제 9-30
// 좌항의 피연산자가 null 또는 undefined이면 우항의 피연산자를 반환,
// 그렇지 않으면 좌항의 피연산자를 반환함
var foo = null ?? 'default string';
console.log(foo); // "default string"
• null 병합 연산자 : ES11에서 도입됨. 연산자 ??는 좌항의 피연산자가 null 또는 undefined인 경우 우항의 피연산자를 반환하고, 그렇지 않으면 좌항의 피연산자를 반환. 변수에 기본값을 설정할 때 유용하다.
// 예제 9-31
var foo = '' || 'default string';
console.log(foo); // "default string"
- Falsy 값인 0이나 ''도 기본값으로 유효하다면 예기치 않는 동작이 발생할 수 있다.
// 예제 9-32
// 좌항의 피연산자가 Falsy 값이라도 null 또는 undefined가 아니면 좌항의 피연산자를 반환한다.
var foo = '' ?? 'default string';
console.log(foo); // ""
- null 병합 연산자 ??는 좌항의 피연산자가 false로 평가되는 Falsy 값이라도 null 또는 undefined가 아니면 좌항의 피연산자를 반환함.
* 위 내용은 모던 자바스크립트 Deep Dive를 참고하여 개인적인 공부를 목적으로 정리하였습니다.
모던 자바스크립트 Deep Dive - 교보문고
자바스크립트의 기본 개념과 동작 원리 | 웹페이지의 단순한 보조 기능을 처리하기 위한 제한적인 용도로 태어난 자바스크립트는 과도하다고 느껴질 만큼 친절한 프로그래밍 언어입니다. 이러
www.kyobobook.co.kr
'Front-End > Javascript' 카테고리의 다른 글
| [JavaScript] 11장 원시 값과 객체의 비교 (0) | 2022.03.18 |
|---|---|
| [JavaScript] 10장 객체 리터럴 (0) | 2022.03.17 |
| [JavaScript] 8장 제어문 (0) | 2022.03.17 |
| [JavaScript] 7장 연산자 (2) (0) | 2022.03.12 |
| [JavaScript] 7장 연산자 (1) (0) | 2022.03.11 |