Home Modern Javascript Deepdive [ Chapter 09 타입 변환과 단축 평가 ]
Post
Cancel

Modern Javascript Deepdive [ Chapter 09 타입 변환과 단축 평가 ]

DesktopView

이 게시물은 SW마에스트로 연수생 간 진행한 Modern JavaScript DeepDive 스터디 개인 정리 내용입니다.
되도록 책의 내용을 그대로 적기보단 개인적으로 인상깊었던 부분을 구어체로 풀어쓰려 노력했습니다.

Modern JavaScript Deep Dive

Chapter _ 09 타입 변환과 단축 평가

이번 챕터는 우리를 속터지게 만드는 타입스크립트의 탄생 배경, 타입 변환에 대한 챕터입니다.

우선 타입을 변환하는 데 있어 개발자의 의도에 따라서

  • 명시적 타입 변환 ( 타입 캐스팅 )
  • 암묵적 타입 변환 ( 타입 강제 변환 )

이렇게 크게 두 가지로 구분됩니다.

여기서 우리를 속터지게 하는 원인이 바로 타입 강제 변환, 즉 암묵적 타입 변환입니다.

타입 변환이란?

사실 명시적 타입 변환이나 암묵적 타입 변환 모두 기존의 원시값을 변경하는 것은 아닙니다.

원시값은 immutable 해서 변경이 불가능하나 여기서 이루어지는 타입변환들은 이러한 기존 immutable 한 원시값들을 활용하여 다른 타입의 새로운 원시값을 생성하는 것을 말합니다.

다음은 그것을 설명하기 위한 예제입니다.

1
2
3
4
5
6
var x = 10
var str = x + '' 

// var 라는 키워드부터가 지금 보기엔 거부감이 들지만 이겨냅시다
console.log(typeof str, str) // string 10
console.log(typeof x ,x ) // number 10

x + ‘’ 를 평가하기 위해 x 변수의 숫자값을 바탕으로 새로운 문자열 값 ‘10’을 생성하고 이것으로 다시 ‘10’ + ‘’ 을 평가하게 됩니다.

여기서 당연하게 생각하시겠지만, 중요한 점은 암묵적으로 변환된 문자열 ‘10’이라는 값은x 변수에 재할당 되지 않았고 사라진다는 점입니다.

정리하자면 현재 자바스크립트에서 이루어지는 암적인 존재 암묵적 타입변환은, 피연산자의 값( x)을 암묵적으로 타입변환하여 새로운 타입의 값( ’10’ ) 을 만들어 단 한번 사용하고 버린다. 가 됩니다.

여기서 암묵적 타입변환은 개발자의 의도가 아닌 자바스크립트 엔진에 의해 암묵적으로 일어나기 때문에 예측하고 사용하지 않는다면 오류가 발생 할 여지가 크게 늘어난다!

⇒ 타입스크립트가 새로운 표준이 된 이유겠죠?

암묵적 타입 변환

자바스크립트 엔진은 특별히 타입이 명시되지 않았다면 코드의 문맥을 고려해서 암묵적으로 타입을 강제 변환합니다.

사실 이 부분은 그간 많이 봐오셨을 “자바스크립트가 이상한 점” 에나 나올법 한 내용들이기도 합니다! (ㅋㅋ)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 문자열 변환
1 + "2" // "12"
0 + "" // "0"

// 숫자 변환
1 - '1' // 0
'1' > 0 // true
+true // 1

1 / "one" // NaN
+{} // NaN
+[] // 0

// 불리언 타입
if ("") console.log(1)
if ("str") console.log(2)
if (0) console.log(3)

// console ==> 2

다 아는 얼굴들이죠?

분명 조그마한 작업이었다면 많은 도움이 되었을 법한 느슨한 문법입니다.

하지만 점점 자바스크립트도 고도화되며 복잡한 로직을 처리하다보면 이런 느슨한 문법에서 휴먼에러가 유도되기 마련입니다.

명시적 타입 변환

“명시적 타입 변환” 이라고 적긴 했지만 우리가 흔히 사용하는 타입 변환들이 모두 명시적 타입 변환에 속합니다.

물론 앞서 사용했던 암묵적 타입 변환을 역으로 이용하는 방법도 명시적 이라는 키워드에 속하기도 하구요.

문자열 타입으로의 변환

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

    1
    2
    
     String(NaN) // “NaN”
     String(1) // “1”
    
  2. .toString 메서드 사용

    1
    2
    
     (1).toString() // "1"
     (true).toString() // "true"
    
  3. 문자열 연결 연산자 이용하기

    1
    
     true+ "" // "true"
    

숫자 타입으로의 변환

  1. Number 생성자 함수를 new 연산자 없이 호출하기

    1
    2
    
     Number(NaN) // “NaN”
     Number(1) // “1”
    
  2. parseInt, parseFloat 메서드 사용 ( 문자열만 가능! )

    1
    2
    
     parseInt("1") // 1
     parseFloat("1.05") // 1.05
    
    • 단항 산술 연산자 이용하기
    1
    
     +"0" // 0
    
    • 산술 연산자 이용하기
    1
    
     "0" * 1 // 0
    

불리언 타입으로의 변환

  1. Boolean 생성자 함수를 new 연산자 없이 호출하기

    1
    2
    
     Boolean(NaN) // false
     Boolean(1) // true
    
  2. ! 부정 논리 연산자를 두 번 사용하는 방법

    1
    2
    
     !!0 // false
     !!1 // true
    

단축 평가

이 부분은 자바스크립트를 조금 사용 해 보신 분이라면 잡기술(?) 같은 느낌으로 자주 접해보셨을법 한 내용입니다.

( 사실 제가 그렇게 접하기도 했구요 )

논리 연산자 표현식의 결과는 불리언 값이 아닐 수 있으며, 논리합&논리곱 연산자의 평가 결과는 언제나 2개의 피연산자 중 한쪽으로 평가된다는 점입니다.

1
2
"Cat" && "Dog" // "Dog"
"Cat" || "Dog" // "Cat"

먼저 && 의 경우엔 둘 다 Truthy 값이면서 앞의 “Cat” 값이 Truthy 값이어서 뒤에 있는 “Dog” 가 반환됩니다.

둘째로 || 의 경우엔 앞의 “Cat” 에서 이미 Truthy 값이 나오기 때문에 바로 “Cat” 이 반환됩니다.

설명이 길어지긴 했지만, 간결한 설명이라면 ‘표현식을 평가하는 도중에 결과가 확정된다면 나머지 평가 과정을 생략하는 것’ 입니다.

옵셔널 체이닝 연산자

이것도 저는 잡기술 같은 느낌으로 접했습니다.

옵셔널 체이닝 ?. 연산자는 좌항의 피연산자가 undefined 인 경우 undefined 를, 그렇지 않으면 우항으로의 프로퍼티 참조를 이어갑니다.

과거엔 && || 논리 연산자를 조합하여 사용했다면 현재는 조금 더 간결하게 그 기능을 사용할 수 있게 되었습니다.

1
2
3
var str = "";
var length = str?.length
// str 이 있는지 체크 후 str의 length를 참조해오게 됨.

null 병합 연산자

위의 옵셔널 체이닝 연산자와 유사하게 좌항의 피연산자를 피교하여 null 혹은 undefined 이라면 우항의 피연산자를, 그렇지 않다면 좌항의 피연산자를 반환합니다.

1
2
var foo = null ?? 'default value'
console.log(foo) // 'default value'
This post is licensed under CC BY 4.0 by the author.