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를 참고하여 개인적인 공부를 목적으로 정리하였습니다.

http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9791158392239&orderClick=LEa&Kc=

 

모던 자바스크립트 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