개발자를 희망하는 초보의 자기개발 이야기

모던 자바스크립트 Deep Dive 9장 타입 변환과 단축 평가 본문

도서/모던 자바스크립트 Deep Dive

모던 자바스크립트 Deep Dive 9장 타입 변환과 단축 평가

클라우드아실 2023. 11. 13. 21:57
반응형

출처 : 예스24

스터디를 진행하면서 책을 읽고 내용과 떠오르는 생각, 용어들을 정리하고 있습니다.
문제 되는 부분이나 틀린 부분이 있다면 편하게 말씀해 주세요.

9장 타입 변환과 단축 평가

9.1.1 타입 변환이란?

자바스크립트의 모든 값은 타입이 있다. 개발자가 의도적으로 타입을 변환하는 것을 '명시적 타입 변환' 또는 '타입 캐스팅'이라 한다. 아래 코드 예시는 숫자 11을 문자열 11로 명시적 타입 변환한 것이다.

var x = 11;

var str = x.toString();

표현식을 평가하는 도중에 자바스크립트 엔진에 의해 암묵적으로 타입이 자동변환 되기도 하는데 이를 '암묵적 타입 변환' 또는 '타입 강제 변환'이라 한다. 아래 코드 예시는 숫자와 문자열을 연산하여 문자열로 강제 형 변환한 것이다.

var str = 1 + '';

 

이러한 형 변환이 기존 원시값을 직접 변경하는 것은 아니다. 타입 변환이란 기존 원시 값을 사용해 다른 타입의 새로운 원시 값을 생성하는 것이다. 즉, 암묵적 타입 변환은 기존 변수 값을 재할당하여 변경하는 것이 아니라 타입 변환해 새로운 타입의 값을 만들어 단 한 번 사용하고 버린다. 타입 변환 결과를 예측하지 못하거나 예측이 결과와 일치하지 않는다면 오류를 생산할 가능성이 높아진다. 중요한 것은 코드를 예측할 수 있어야 한다는 것이다.

9.2 암묵적 타입 변환

암묵적 타입 변환이 발생하면 문자열, 숫자, 불리언과 같은 원시 타입 중 하나로 타입을 자동 변환한다. Symbol 타입은 아래와 같이 타입 에러가 발생한다.

(Symbol()) + '' // TypeError: cannot convert a symbol value to a string

9.2.1 문자열 타입으로 변환

+ 연산자는 피연산자 중 하나 이상이 문자열일 때 문자열 연결 연산자로 동작하고, 모든 피연산자는 문맥상 문자열타입으로 암묵적 타입 변환되어 문자열 값을 반환한다.

1 + '2' // '12'

`1 + 1 = ${1 + 1}` // "1 + 1 = 2"

템플릿 리터럴의 표현식 삽입은 표현식의 평가 결과를 문자열 타입으로 암묵적 타입 변환한다.

9.2.2 숫자 타입으로 변환

+를 제외한 산순 연산자는 숫자 값을 만드는 것이 목표다. 따라서 코드 문맥상 모두 숫자 타입으로 강제 형 변환하여 평가 후 결과를 반환한다. 

1 - '1' // 0
1 * 'one' // NaN

비교 연산자의 역할은 불리언 값을 만드는 것으로 숫자 타입이 아닌 피연산자를 숫자 타입으로 암묵적 타입 변환한다. 빈 문자열( '' ), 빈 배열( []), null, false는 0으로, true는 1로 변환되고, 객체와 빈 배열이 아닌 그 외 배열, undefined는 반환되지 않아 NaN이 된다.

+'' // 0
+null // 0
+[] // 0
+false // 0

9.2.3 불리언 타입으로 변환

자바스크립트 엔진은 불리언 타입이 아닌 값을 Truthy 값(참으로 평가되는 값) 또는 Falsy 값(거짓으로 평가되는 값)으로 구분한다. 불리언 값으로 평가되어야 할 문맥에서 Truthy 값은 true로, Falsy 값은 false로 암묵적 타입 변환된다.

  Falsy 값이란?
 : Boolean 문맥에서 false 로 평가되는 값이다. false, undefined, null, 0, -0, NaN, ''(빈 문자열)

9.3 명시적 타입 변환

명시적 타입 변환의 방법에는 표준 빌트인 생성자 함수(String, Number, Boolean)를 new 연산자 없이 호출하는 방법과 빌트인 메서드를 사용하는 방법, 암묵적 타입 변환 방법이 있다.

  표준 빌트인 생성자 함수와 빌트인 메서드란?
 :자바스크립트에서 기본 제공하는 함수로, 표진 빌트인 생성자 함수는 객체를 생성하기 위한 함수이며 new 연산자와 함께 호출한다. 표준 빌트인 메서드는 String, Number와 같은 new 연산자 없이 사용하는 메서드로 빌트인은 '미리 만들어진'을 의미한다. 

9.3.1 문자열 타입으로 변환

문자열 타입으로 변환하는 방법은 아래와 같다.

  1. String 생성자 함수를 new 연산자 없이 호출하는 방법
  2. toString 메서드를 사용하는 방법
  3. 문자열 연결 연산자를 이용하는 방법
1. String 생성자 함수를 new 연산자 없이 호출하는 방법
String(126);

2. toString 메서드를 사용하는 방법
(126).toString();

3. 문자열 연결 연산자를 이용하는 방법
126 + '';

9.3.2 숫자 타입으로 변환

숫자타입으로 변환하는 방법은 아래와 같다.

  1. Number 생성자 함수를 new 연산자 없이 호출하는 방법
  2. parseInt.parseFloat 함수를 사용하는 방법(문자열만 가능)
  3. + 단항 산술 연산자를 이용하는 방법
  4. * 산술 연산자를 이용하는 방법
1. Number 생성자 함수를 new 연산자 없이 호출하는 방법
Number('10.51'); // 10.53

2. parseInt.parseFloat 함수를 사용하는 방법(문자열만 가능)
parseInt('-1'); // -1

3. + 단항 산술 연산자를 이용하는 방법
+ '0'; // 0

4. * 산술 연산자를 이용하는 방법
true * 1; // 1

9.3.3 불리언 타입으로 변환

  1. Boolean 생성자 함수를 new 연산자 없이 호출하는 방법
  2. ! 부정 논리 연산자를 두 번 사용하는 방법
1. Boolean 생성자 함수를 new 연산자 없이 호출하는 방법
Boolean('x'); // true

2. ! 부정 논리 연산자를 두 번 사용하는 방법
!!null; // false

 그런데 불리언 타입은 굳이 이렇게 쓸 상황이 생길까 싶다..;

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

논리합( || ) 또는 논리곱( && ) 연산자 표현식은 언제나 2개의 피연산자 중 한쪽으로 평가된다.

'Cat' && 'Dog' // "Dog"

위와 같이 두 개의 피연산자가 모두 true로 평가될 때 true를 반환한다. 좌항에서 우항으로 평가가 진행되는데 'Cat'은 Truthy 값이므로 true로 평가되되는데 앞서 이야기한 대로 &&은 두 개의 피연산자가 모두 평가되어야 표현식의 평가 결과가 결정되기 때문에 'Dog'도 평가되고, 'Dog'도 마찬가지로 true로 평가된다. 이때 둘 다 true라면 최종 평가된 'Dog'가 반환된다.

'Cat' || 'Dog' // "Cat"

논리합 경우 두 개의 피연산자 중 true가 나오면 그 이후 피연산자는 평가하지 않아도 표현식을 평가할 수 있다. 그래서 'Cat'이 그대로 반환되고 'Dog'는 평가하지 않게 된다. 이처럼 논리 연산의 결과를 결정하는 피연산자를 타입 변환하지 않고 그대로 반환하는데 이를 단축 평가라 한다. 단축평가는 표현식을 평가하는 도중에 평가 결과가 확정된 경우 나머지 평가 과정을 생략하는 것을 말한다. 아래 두 if문을 보면 첫 번째 if문은 우항이 평가되지 않아 (num+=15)가 평가되지 않는다.

let num = 1;

if((4 > 0) || (num += 15)) {
  console.log(num)
}

if((num +=1) || (4 > 0)) {
  console.log(num)
}

단축 평가를 사용하면 if 문을 대체할 수 있는데 React에서 if문을 쓸 일이 잘 없기 때문에 삼항연산자를 많이 사용하듯이 단축 평가도 자주 사용하게 되니 잘 익혀두어야 한다.

var left = true;

var message ='';

message = left && '완료'

console.log(message); // 완료

9.4.1 함수 매개변수에 기본 값을 설정할 때

함수를 호출할 때 인수를 전달하지 않으면 매개변수에는 undefined가 할당된다. 이 때 단축평가를 사용해 기본값을 설정하면 undefined로 인해 발생할 수 있는 에러를 방지할 수 있다. 아래의 두 코드는 동일한 결과를 반환하는데 두 번째 코드는 ES6의 문법으로 매개변수에 초기값을 아예 할당할 수 있다는 장점이 있다.

function getStringLength(str) {
  str = str || '';
  return str.length;
}

function getSTringLength(str = ''){
  return str.length;
}

getSTringLength(); // 0
getSTringLength('hi'); // 2

9.4.2 옵셔널 체이닝 연산자

ES11에서 도입된 옵셔널 체이닝 연산자 ?. 는 좌항의 피연산자가 null 또는 undefined인 경우 undefined를 반환하고, 그렇지 않으면( 피연산자라 Falsy 값이라도 ) 우항의 프로퍼티 참조를 이어간다. 선언이 완료된 변수를 대상으로만 동작한다. 예를 들어 어떤 게임에 캐릭터 객체가 있는데 이 객체에 지력, 힘, 체력, 마력 등 여러 프로퍼티가 있다고 치자. 그런데 여러 캐릭터 중 '천사' 캐릭터는 '마력'이라는 프로퍼티가 어울리지 않아서 '천사' 캐릭터 객체를 만든 적이 있다면 이 '마력' 프로퍼티를 삭제해주고 싶은 거다. 아래 코드와 같이 표현할 수 있다.

let 천사 = {
  힘 : 20,
  지력 : 20,
  마력 : 250
}

delete 천사?.마력 // 힘, 지력 프로퍼티만 남게 된다.

챗 GPT에게 옵셔널 체이닝에 대해 물어보고 추가적인 예시 코드를 받았다. 객체의 속성이나 메서드에 안전하게 접근하기 위한 기술 중 하나로, 아래와 같이 중첩된 객체에서 하위 객체가 존재하지 않을 수 있는 상황에서 유용하게 활용할 수 있다고 한다.

// 객체 A가 중첩된 상황을 가정
const objectA = {
  // 객체 B가 존재하지 않을 수 있음
  objectB: {
    // 객체 C가 존재하지 않을 수 있음
    objectC: {
      // 실제 값
      value: "Hello, Optional Chaining!",
    },
  },
};

// 옵셔널 체이닝을 사용하여 안전하게 속성에 접근
const result = objectA?.objectB?.objectC?.value;

console.log(result); // 만약 어느 하나라도 존재하지 않으면 undefined 출력

null 또는 undefined 인지 판단할 때 삼항 연산자의 축약형같은 느낌으로 사용할 수도 있다.

var go = "";

var result = go?.length; // 0

변수 go 가 null이나 undefined인지 판별시도후
둘 다 아니기 때문에 0이 할당된다.

정리

역시 악명높은 자바스크립트답게 타입변환에 대해서도 예외사항이 많아 어떤 형식이 반환되거나 타입에러가 나타나는지 다 외우기는 어려울 것 같다. 일단 코테에서 많이 사용하니까 기본적으로 문자열, 숫자열 형 변환은 알고 있다. 옵셔널 체이닝 연산자는 책만 봐서는 감이 안잡혀서 Chat GPT 선생님의 도움을 추가로 구했다. 세상이 좋아져서 기한을 주고 프론트엔드 개발자 공부 커리큘럼을 짜달라고 하니까 커리큘럼도 짜준다.;; 아직 9장인데 단원별로 깊은 내용들이 있어서 좀 무서워지고 있는데 Chat GPT 선생님과 함께 진행해야겠다.

반응형