모던 JS DeepDive(9장)

Minji Lee·2024년 1월 22일
0
post-thumbnail

[9장] 타입 변환과 단축 평가

9.1 타입 변환이란?

명시적 타입 변환(= 타입 캐스팅): 개발자가 의도적으로 값의 타입을 변환하는 것

암시적 타입 변환(=타입 강제 변환): 개발자 의도와 상관없이 표현식을 평가하는 도중 JS 엔진에 의해 암묵적으로 타입 자동 변환

❗️타입 변환은 기존 원시값을 직접 변경하는 것이 아니라, 기존 원시 값 이용하여 다른 타입의 새로운 원시 값 생성하는 것


9.2 암시적 타입 변환

JS엔진은 표현식 평가할 때 개발자의 의도와 상관없이 코드의 문맥 고려해 암묵적으로 데이터 타입을 강제 변환

  • 의도치 않게 에러를 발생시킬 수 있음

9.2.1 문자열 타입으로 변환

  1. + 연산자는 피연산자 중 하나 이상이 문자열인 경우 문자열 연결 연산자로 동작

    1 + '2' // "12"
  2. 템플릿 리터럴의 표현식 삽입

    `1 + 1 = ${1+1}` // "1 + 1 = 2"
  3. 이외의 방식

    // 숫자 타입
    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 숫자 타입으로 변환

  1. -, *, / 연산자를 통해 숫자 값으로 만듦
  • 단, 모든 피연산자는 모두 숫자 타입이어야 함! ⇒ 숫자 타입이 아니면 NaN이 됨
     1 - '1' // 0
     1 * '10' // 10
     1 / 'one' // NaN
     ```
    
  1. 비교 연산자는 피연산자의 크기 비교하여 불리언 값 만듦

    • 단, 모든 피연산자는 모두 숫자 타입이어야 함!
      '1' > 0 // true
  2. + 단항 연산자로 피연산자가 숫자 타입이 아닌 경우 숫자 타입의 값으로 타입 변환

    // 문자열 타입
    +'' // 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 String
    
    // 객체 타입
    +{} // NaN
    +[] // 0
    +[10, 20] // NaN
    +(function(){}) // NaN
    • 빈 문자열(’’), 빈 배열([]), null, false0
    • true1
    • 객체, 빈 배열 아닌 배열, undefinedNaN

9.2.3 불리언 타입으로 변환

JS 엔진은 불리언 타입이 아닌 값을 Truthy 값 또는 Falsy 값으로 구분

  • false로 평가되는 Falsy 값false, undefined, null, ‘’, 0, -0, NaN
  • 위의 값 이외의 값들은 모두 true로 평가됨

9.3 명시적 타입 변환

개발자 의도에 따라 명시적으로 타입 변경

9.3.1 문자열 타입으로 변환

  1. String 생성자 함수를 new 연산자 없이 호출하는 방법

    // 숫자 타입 => 문자열 타입
    String(1); // '1'
    String(NaN); // 'NaN'
    String(Infinity); // 'Infinity'
    // 불리언 타입 => 문자열 타입
    String(true); // 'true'
    String(false); // '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 숫자 타입으로 변환

  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 불리언 타입으로 변환

  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
    // undefined 타입 => 불리언 타입
    Boolean(undefined); // false
    // 객체 타입 => 불리언 타입
    Boolean({}); // true
    Boolean([]); // true
  2. ! 부정 논리 연산자두 번 사용하는 방법

    // 문자열 타입 => 불리언 타입
    !!'x'; // true
    !!''; // false
    !!'false'; // true
    // 숫자 타입 => 불리언 타입
    !!0; // false
    !!1; // true
    !!NaN; // false
    !!Infinity; // true
    // null 타입 => 불리언 타입
    !!null; // false
    // undefined 타입 => 불리언 타입
    !!undefined; //false
    // 객체 타입 => 불리언 타입
    !!{}; // true
    !![]; // true

9.4 단축 평가

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

논리곱(&&) 연산자논리합(||) 연산자는 논리 연산의 결과를 결정하는 피연산자를 타입 변환하지 않고 그대로 반환 ⇒ 단축 평가

단축 평가: 표현식을 평가하는 도중에 평가 결과가 확정된 경우 나머지 평가 과정을 생략

  • 논리곱(&&) 연산자: 두 개의 피연산자가 모두 true로 평가될 때 true로 반환 ⇒ 좌항에서 우항으로 평가 진행
  • 논리합(||) 연산자: 두 개의 피연산자 중 하나만 true로 평가되어도 true로 반환 ⇒ 좌항에서 우항으로 평가 진행
단축 평가 표현식평가 결과
true || anythingtrue
false || anythinganything
true && anythinganything
false && anythingfalse
// 논리합(||) 연산자
'Cat' || 'Dog'; // 'Cat'
false || 'Dog'; // 'Dog'
'Cat' || false; // 'Cat'

// 논리곱(&&) 연산자
'Cat' && 'Dog'; // 'Dog'
false && 'Dog'; // false
'Cat' && false; // false
  • if문 대체 가능
    // 논리곱 연산자로 if문 대체
    var done = true;
    var message = '';
    
    // 이 if문을
    if (done) message = '완료';
    // 이렇게 작성 가능
    message = done && '완료';
    console.log(message); // 완료
    // 논리합 연산자로 if문 대체
    var done = false;
    var message = '';
    
    // 이 if문을
    if (!done) message = '미완료';
    // 이렇게 작성 가능
    message = done || '미완료';
    console.log(message); // 미완료
  • 객체를 가리키기를 기대하는 변수가 null 또는 undefined가 아닌지 확인하고 프로퍼티 참조
    // 가리키는 프로퍼티가 null 혹은 undefined인 경우 타입 에러 발생!!!!
    var elem = null;
    var value = elem.value; // TypeError: Cannot read property 'value' of null
    var elem = null;
    // elem이 null이나 undefined이면 elem으로 평가되고
    // elem이 Truthy 값이면 elem.value로 평가
    var value = elem && elem.value; // null
  • 함수 매개변수에 기본값 설정할 때 ⇒ 함수 호출 시 인수 전달하지 않으면 매개변수에 undefined 할당됨
    function getStringLength(str){
    	str = str || '';
    	return str.length;
    }
    
    getStringLength(); // 0
    getStringLength('hi'); // 2

9.4.2 옵셔널 체이닝 연산자

옵셔널 체이닝 연산자 ?.는 좌항의 피연산자가 null 또는 undefined인 경우 undefined 반환, 그렇지 않으면 우항의 프로퍼티 참조 ES11부터 도입됨

var elem = null;
var value = elem?.value;
console.log(value); // undefined
  • 이전에는 논리 연산자로 평가함 ⇒ Falsy 값이면 좌항 피연산자를 그대로 반환하는데 0이나 ‘’인 경우는 객체로 평가될 때에도 있음
    var str = '';
    
    // 문자열의 길이를 참조
    var length = str && str.length;
    
    // 문자열의 길이 참조 못함
    console.log(length); // ''
  • 이때, 옵셔널 체이닝 연산자 사용
    var str = '';
    
    // 문자열의 길이를 참조
    var length = str?.length;
    
    // 문자열의 길이 참조 못함
    console.log(length); // 0

9.4.3 null 병합 연산자

null 병합 연산자 ??는 좌항의 피연산자가 null 또는 undefined인 경우 우항의 피연산자를 반환하고, 그렇지 않으면 좌항의 피연산자를 반환 ⇒ ES11 부터 도입

var foo = null ?? 'default string';
console.log(foo); // 'default string'
  • 기본값 설정할 때 유용
    var foo = '' ?? 'default string';
    console.log(foo); // ''

0개의 댓글