[JS Deep Dive] 9장. 타입변환과 단축평가

lyshine·2023년 3월 30일
0

JS Deep Dive 정리

목록 보기
6/18

타입 변환이란?

  • 자바스크립트의 모든 값은 타입이 있다.
  • 의도적으로 값의 타입을 변환하는 것을 명시적 타입 변환 또는 타입 캐스팅이라 한다.
  • 의도와 상관없이 자바스크립트 엔진에 의해 암묵적으로 자동 타입변환되는 것을 암묵적 타입 변환 또는 타입 강제 변환이라 한다.
  • 이때 타입변환이 일어날때 기존 원시 값이 변경되는 것이 아닌 다른 타입의 새로운 원시 값을 생성한다.
  • 코드를 예측할 수 있도록 타입 변환을 이해하고 사용해야 한다.
var x = 10;
//명시적 타입변환
var str = x.toString();
//암묵적 타입변환
var str2 = x + '';

암묵적 타입 변환

문자열 타입으로 변환

  • 문자열 타입이 아닌 피연산자를 문자열 타입으로 암묵적 타입 변환한다.
// 숫자 타입
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] }"

숫자 타입으로 변환

  • 산술 연산자의 피연산자 중에서 숫자 타입이 아닌 피연산자를 숫자 타입으로 암묵적 타입 변환한다.
  • 피연산자를 숫자 타입으로 변환할 수 없는 경우는 NaN이 결과값이 된다.
  • 산술 연사자 뿐만 아니라 비교연산자도 숫자타입으로 암묵적 타입 변환한다.
  • ‘+’단항 연산자
1 - '1'    // 0
1 * '10'   // 10
1 / 'one'  // NaN

'1' > 0   // true

// 문자열 타입
+''             // 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

// 빈 문자열(‘’), 빈 배열([]), null, false는 0
//true는 1로 변환 
//객체({})와 빈 배열이 아닌 배열 undefined는 변환되지 않아 NaN

불리언 타입으로 변환

  • 조건식의 평가 결과를 불리언 타입으로 암묵적 타입 변환한다.
  • false로 평가되는 값 이외에는 모두 true로 평가되는 값이다.
  • false로 평가되는 Falsy값
    • false
    • undefined
    • null
    • 0, -0
    • NaN
    • ‘’(빈 문자열)
// 주어진 인자가 Falsy 값이면 true, Truthy 값이면 false를 반환한다.
function isFalsy(v) {
  return !v;
}

// 주어진 인자가 Truthy 값이면 true, Falsy 값이면 false를 반환한다.
function isTruthy(v) {
  return !!v;
}

// 모두 true를 반환한다.
console.log(isFalsy(false));
console.log(isFalsy(undefined));
console.log(isFalsy(null));
console.log(isFalsy(0));
console.log(isFalsy(NaN));
console.log(isFalsy(''));

console.log(isTruthy(true));
// 빈 문자열이 아닌 문자열은 Truthy 값이다.
console.log(isTruthy('0'));
console.log(isTruthy({}));
console.log(isTruthy([]));

명시적 타입 변환

  • 개발자의 의도에 따라 명시적으로 타입을 변환하는 방법은 다양하다.

문자열 타입으로 변환

  • String 생성자 함수를 new 연산자 없이 호출하는 방법
  • Object.prototype.toString 메서드를 호출하는 방법
  • 문자열 연결 연산자를 이용하는 방법
// 1. String 생성자 함수를 new 연산자 없이 호출하는 방법
// 숫자 타입 => 문자열 타입
console.log(String(1));        // "1"
console.log(String(NaN));      // "NaN"
console.log(String(Infinity)); // "Infinity"
// 불리언 타입 => 문자열 타입
console.log(String(true));     // "true"
console.log(String(false));    // "false"

// 2. Object.prototype.toString 메소드를 사용하는 방법
// 숫자 타입 => 문자열 타입
console.log((1).toString());        // "1"
console.log((NaN).toString());      // "NaN"
console.log((Infinity).toString()); // "Infinity"
// 불리언 타입 => 문자열 타입
console.log((true).toString());     // "true"
console.log((false).toString());    // "false"

// 3. 문자열 연결 연산자를 이용하는 방법
// 숫자 타입 => 문자열 타입
console.log(1 + '');        // "1"
console.log(NaN + '');      // "NaN"
console.log(Infinity + ''); // "Infinity"
// 불리언 타입 => 문자열 타입
console.log(true + '');     // "true"
console.log(false + '');    // "false"

숫자 타입으로 변환

  • Number 생성자 함수를 new 연산자 없이 호출하는 방법
  • parseInt, parseFloat 함수를 사용하는 방법(문자열만 숫자 타입으로 변환 가능)
    • 단항 산술연산자를 이용하는 방법
    • 산술 연산자를 이용하는 방법
// 1. Number 생성자 함수를 new 연산자 없이 호출하는 방법
// 문자열 타입 => 숫자 타입
console.log(Number('0'));     // 0
console.log(Number('-1'));    // -1
console.log(Number('10.53')); // 10.53
// 불리언 타입 => 숫자 타입
console.log(Number(true));    // 1
console.log(Number(false));   // 0

// 2. parseInt, parseFloat 함수를 사용하는 방법(문자열만 변환 가능)
// 문자열 타입 => 숫자 타입
console.log(parseInt('0'));       // 0
console.log(parseInt('-1'));      // -1
console.log(parseFloat('10.53')); // 10.53

// 3. + 단항 연결 연산자를 이용하는 방법
// 문자열 타입 => 숫자 타입
console.log(+'0');     // 0
console.log(+'-1');    // -1
console.log(+'10.53'); // 10.53
// 불리언 타입 => 숫자 타입
console.log(+true);    // 1
console.log(+false);   // 0

// 4. * 산술 연산자를 이용하는 방법
// 문자열 타입 => 숫자 타입
console.log('0' * 1);     // 0
console.log('-1' * 1);    // -1
console.log('10.53' * 1); // 10.53
// 불리언 타입 => 숫자 타입
console.log(true * 1);    // 1
console.log(false * 1);   // 0

불리언 타입으로 변환

  • Boolean 생성자 함수를 new 연산자 없이 호출하는 방법
  • ! 부정 논리 연산자를 두번 사용하는 방법(!!)
// 1. Boolean 생성자 함수를 new 연산자 없이 호출하는 방법
// 문자열 타입 => 불리언 타입
console.log(Boolean('x'));       // true
console.log(Boolean(''));        // false
console.log(Boolean('false'));   // true
// 숫자 타입 => 불리언 타입
console.log(Boolean(0));         // false
console.log(Boolean(1));         // true
console.log(Boolean(NaN));       // false
console.log(Boolean(Infinity));  // true
// null 타입 => 불리언 타입
console.log(Boolean(null));      // false
// undefined 타입 => 불리언 타 입
console.log(Boolean(undefined)); // false
// 객체 타입 => 불리언 타입
console.log(Boolean({}));        // true
console.log(Boolean([]));        // true

// 2. ! 부정 논리 연산자를 두번 사용하는 방법
// 문자열 타입 => 불리언 타입
console.log(!!'x');       // true
console.log(!!'');        // false
console.log(!!'false');   // true
// 숫자 타입 => 불리언 타입
console.log(!!0);         // false
console.log(!!1);         // true
console.log(!!NaN);       // false
console.log(!!Infinity);  // true
// null 타입 => 불리언 타입
console.log(!!null);      // false
// undefined 타입 => 불리언 타입
console.log(!!undefined); // false
// 객체 타입 => 불리언 타입
console.log(!!{});        // true
console.log(!![]);        // true

단축 평가

논리 연산자를 사용한 단축 평가

  • 논리합(||), 논리곱(&&) 연산자 표현식의 평가 결과는 불리언 값이 아닐 수도 있다.
'Cat' && 'Dog' //"Dog"
'Cat' || 'Dog' //"Cat"

// 논리합(||) 연산자
'Cat' || 'Dog'  // 'Cat'
false || 'Dog'  // 'Dog'
'Cat' || false  // 'Cat'

// 논리곱(&&) 연산자
'Cat' && 'Dog'  // Dog
false && 'Dog'  // false
'Cat' && false  // false
  • 단축평가는 표현식을 평가하는 도중에 평가 결과가 확정된 경우 나머지 평가 과정을 생략하는 것을 말한다.
단축 평가 표현식평가 결과
true
false
true && anythinganything
false && anythingfalse
  • 단축 평가를 사용하면 if문을 대체할 수 있다.
    • 조건이 true일때 논리곱(&&)으로 대체
    • 조건이 false일때 논리합(||)으로 대체
var done = true;
// 주어진 조건이 true일때
if(done) message = '완료';
//&&로 대체
//done이 ture라면 message에 '완료'를 할당
var message = done && '완료';

var done = false;
// 주어진 조건이 false일때
if(!done) message = '미완료';
//||로 대체
//done이 false라면 message에 '미완료'를 할당
var message = done || '미완료';
  • 객체가 null인지 확인하고 프로퍼티를 참조할 때
var elem = null;

console.log(elem.value); // TypeError: Cannot read property 'value' of null

// 단축평가를 사용하면 에러를 발생시키지 않는다.
// elem이 null이나 undefined와 같은 Falsy값이면 elem으로 평가되고
// elem이 Truthy 값이면 elem.value로 평가된다.
console.log(elem && elem.value); // null

// 뒤에서 나오는 옵셔널 체이닝 연산자로도 대체가능(?.)
  • 함수의 매개변수에 기본값을 설정할때
    • 함수를 호출할때 인수를 전달하지 않으면 매개변수에는 undefined가 할당된다. 이때 단축평가를 이용해 매개변수의 기본값을 설정할 수도 있다.
// 단축 평가를 사용한 매개변수의 기본값 설정
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

옵셔널 체이닝 연산자(?.)

  • 옵셔널 체이닝 연산자 ?. 는 좌항의 피연산자가 null 또는 undefined인 경우 undefined를 반환하고 그렇지 않으면 우항의 프로퍼티 참조를 이어간다.
  • && 의 역할도 대신하지만 차이점이 있다.
    • 논리곱 &&는 좌항 피연산자가 Falsy값이면 좌항 피연산자를 그대로 반환하지만 옵셔널 체이닝 연산자 ?. 는 좌항 피연산자가 Falsy값이라도 null,undefined가 아니면 우항의 참조를 이어간다.
var elem = null;

//elem이 null or undefined 이면 undefined를 반환하고 그렇지 않으면 우항의 프로퍼티 참조를 이어간다.
var value = elem?.value;
console.log(value); //undefined

var str = '';
var length = str && str.length;
// str.length 를 참조하지 못한다.
console.log(length); // ''

var length2 = str?.length;
//str이 Falsy값이지만 null/undefined가 아니므로 length를 참조한다.
console.log(length2); // 0

null 병합 연산자

  • null 병합 연산자 ?? 는 좌항의 피연산자가 null or undefined 인 경우 우항의 피연산자를 반환하고 그렇지 않으면 좌항의 피연산자를 반환한다.
  • 변수에 기본값을 설정할 때 유용하다.
  • || 의 역할도 대신하지만 차이점이 있다.
var foo = null ?? 'default string';
console.log(foo); //"default string"

//Falsy값
var foo = '' || 'default string';
console.log(foo); // "default string"

//좌항의 피연산자가 Falsy값이어도 null/undefined가 아니므로 좌항의 피연산자를 반환한다.
var foo = '' ?? 'default string';
console.log(foo); ""

0개의 댓글