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

young_pallete·2022년 8월 30일
0

REAL JavaScript Deep Dive

목록 보기
10/46
post-custom-banner

🌈 시작하며

이 파트가 이 책에는 없을 줄 알았는데, 있군요!

암묵적, 명시적 타입 변환은 음... 정~말 다양한 방법들이 많아서 쓰기가 골치 아픈 애증의 파트입니다. 😭

사실 어떤 게 더 좋다!라고 말하기는 굉장히 모호하기는 합니다. 아무래도 팀 컨벤션에 따라 크게 갈릴 것 같아요. 어떤 사람은 명시적인 방법으로 하는 게 편할 수도, 아니면 암시적인 변환이 더 편할 수 있거든요.
(저는 보통 명시적인 변환을 선호하지만, 가독성을 해치지 않는 선에서 섞어 씁니다.)

다만, 어떤 사람들이 팀으로 들어올지 모르고, 제가 어떤 팀에 들어갈지 모르기에 이 개념을 익히는 건 나쁘지 않을 거 같아요. 시작해보죠!

🚦 본론

이전 글에서 살펴 보았듯이,

  • 명시적인 타입 변환은 개발자가 의도를 갖고 코드에 명시적으로 타입을 변경하는 거에요.
  • 암묵적인 타입 변환은 표현식을 평가하는 도중에 자바스크립트 엔진이 타입을 변환하는 거에요.

즉 변환의 과정을 누가 맡느냐가 이 두 개념의 핵심입니다.

아마 대부분의 개발자가 헷갈리는 부분은 후자일 거 같아요. 명시적이라는 건 코드에 반영되므로 꽤나 코드가 선언적이기 때문이죠.

그래서 이 파트를 어떻게 쓸까 고민했는데... 음, 어려운 동작 원리는 부연설명하면서 저 두 개념을 비교하며 어떤 변환 방법들이 있는지 살피는 게 좋을 거 같군요!

문자열이 아닌 값을 문자열로 변환

명시적 타입 변환

// 문자열로 변환. 
const a = 1;
a.toString() // '1'

// toString 메서드가 없는 타입 객체는 `String`을 쓰면 됩니다!
String(null) // 'null'
String(undefined) // 'undefined'

// JSON 문자열
const b= {}
JSON.stringify(b) // "{}"
JSON.stringify(undefined) // null - JSON 문자열화가 불가능하면 null로 바꿔줘요.

암묵적 타입 변환

+ 연산에서 문자열을 더하는 연산이 들어간다면, 이를 문자열 연산으로 인식하고 자바스크립트 엔진이 암묵적으로 문자열 연산을 하게 돼요! 🙇🏻‍♂️

const a = 1;
a + '' // '1'
a + '3' // '13'
true + ''// 'true'
null  + '' // 'null'

var b;
b + '' // 'undefined'

숫자 타입으로 변환

명시적 타입 변환

// parseInt, parseFloat 사용
parseInt('123') // 123
parseInt('17F') // 17, parseInt, ParseFloat는 일단 문자열로 값을 바꾼다음, 순차적으로 계산하여 만약 숫자로 변환할 수 없는 값이 나오면 이전의 값을, 이전의 값이 없다면 NaN을 반환해요!

parseFloat('23.2') // 23.2

// Number 사용
const a = "23"
const b = [1,2,3]

Number(a) // 23
Number(b) // NaN

암묵적 타입 변환

단항 연산자로써 기능하는 +를 통해 암시적으로 숫자로 변환할 수 있어요!

+"51" // 51
+true // 1s
+null // 0
+undefined // NaN, `+`은 할당된 값을 숫자로 변환할 수 있다면 변환시켜주는데, `undefined`는 할당된 값이 없는 것으로 인식해요!

0 | 3 // OR 연산자를 통한 ToInt32 변환
0 | Infinity // 0, Infinity는 64비트 표준이므로 계산 불가능하여 0
0 | NaN // 0, Infinity와 마찬가지의 이유

~42 // 틸드 연산자를 통해 비트 연산, -(숫자 + 1)의 연산을 수행
~Infinity // -1, 32비트로 강제변환하는 과정에서 `Infinity`는 0으로 변환, -(0 + 1) = -1

"22" - 2 // 20, + 연산자가 아닌 -, *, /, % 등의 연산자는 문자열을 숫자로 해석하고 연산

여기서 좀 더 레벨업을 하면, 이 친절한 자바스크립트와 개발자 동료들에게 엄청난 혼란을 줄 수 있답니다! 우리는 그것을 닌자 코드라 부르기로 했어요 😭

+[] // 0
{} + [] // 0
[] + [] // ''
({}) + [] // "[object Object]"

저도 장난치다가 신기해서 찾아봤더니 생각해 보지 못한 새로운 결과가 나오네요 😮
한 번 이에 관해서 또 블로그 글을 따로 써봐야겠어요! 🤣


불리언 타입 변환

명시적 타입 변환

Boolean('1') // true
Boolean('') // false

Boolean(0) // false
Boolean([]) // true

암묵적 타입 변환

!!을 통해 암묵적으로 boolean 타입으로 변환이 가능하답니다 😉

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

!![] // true
!!'' // false

단축 평가(쇼트 서킷)

이제 단축 평가를 알아보아야 할 차례군요?!
이건 실제로 엄~청 많이 쓰이는 거기 때문에, 꼭 익히시길 권장 드릴게요.

쉽게 말하자면, &&||가 굳이 이미 결론이 난 것에 대해서는 더이상 평가하지 않는다는 것에서 착안된 방식이에요.

우리, 한 번 생각해봐요.
만약에 1에 0을 곱한 다음, 임의의 정수로 10억 번 더 곱한 코드를 짰다고 생각해봅시다.
혹시 답을 아시겠나요?

우리가 알 수 있는 이유는, 이미 결론이 난 직후에는 더이상 10억 번이라는 횟수를 생각하지 않아도 되기 때문이에요.

논리 연산에 대한 평가도 마찬가지에요.
만약 OR(||) 문이었는데, 이미 결과가 true라면? 더이상 생각할 필요가 없어요.
만약 AND(&&) 문이었는데, 이미 결과가 false라면? 얘도 더이상 생각팔 필요가 없겠죠!

따라서 이렇게 나머지 평가 과정을 생략하는 것을 쇼트 서킷이라 해요.
이것이 좀 더 실무적으로 응용되면, 다음과 같이 truthy, falsy한 값을 바탕으로 신세계가 펼쳐진답니다!

const a = document.querySelector('input');

a && a.focus(); // input이 있다면 해당 `input`을 포커스해라!

// type이 이미 선언되었다고 가정
const card = {};
const DEFAULT_VALUE = 'default';

card.type = type || DEFAULT_VALUE; // 먼약 `type`이라는 값이 falsy하다면 디폴트 값으로 넣어라!

이런 식으로, 값이 어떻게 나올지에 따라서 마치 조건문처럼 분기처리를 해줄 수 있기도 하고(&&) 추가적인 할당식 없이 깔끔하게 코드를 단축시킬 수도 있어요!

옵셔널 체이닝 연산자

이거 정말 많이 사용하고 있어요. 위의 &&을 통한 객체 프로퍼티 관련한 쇼트 서킷을 거의 대체할 정도로 말이죠!

이는 객체에 접근할 때처럼 체이닝이 가능한데요!
만약 ?. 왼쪽의 값이 undefinednull이라면 undefined를, 아니라면 해당 프로퍼티 값에 접근할 수 있게 해준답니다!

const obj = {
  a: {
	b: 1
  }
}

obj?.c // undefined
obj?.a // {b: 1}
obj?.a?.b // 1
obj?.a?.c // undefined
obj?.c?.d // undefined

원래였다면 분명 접근할 수 없는 값이기 때문에 에러가 떴어야 하는데, undefined로 해석이 되지요?!
이런 에러를 내뱉지 않는 안정성 있는 코드 문법 덕분에(경우에 따라서는 안 좋을 수 있겠지만요 🥲), 실제로 많이 애용하고 있는 연산자 중 하나랍니다 🥰

널 병합 연산자

이건 정말 쉽고 강력한 최근 문법인데요! (ES11)
null이나 undefined 값이 들어올 경우 ?? 연산자의 정해진 우측 값으로 대체하는 연산자에요!

const NULL = null;
const a = NULL ?? true // true

const UNDEFINED = undefined;
const b = UNDEFINED ?? false // false

✨ 마치며

후... 확실히 슬슬 코드 예제들이 생겨나니, 이를 다시 톺아보는 시간이 꽤나 걸렸네요.
그렇지만 오늘 이걸 배우면서, + 연산자에 대한 심오한 과정들을 다시 깨달아서 기분이 좋아요! 또한, 틸드와 OR 연산자를 응용하는 과정 역시 살펴보아서, 차근차근 몰랐던 부분들을 짚어나가는 것이 좋았답니다 :)

그럼, 다들 즐거운 코딩하시길 바라요. 이상! 🌈

profile
People are scared of falling to the bottom but born from there. What they've lost is nth. 😉
post-custom-banner

0개의 댓글