ARTICLE | [JS] 타입 변환과 단축 평가

noopy·2021년 9월 15일
0

✏️ STUDY

목록 보기
3/10

팀원들과 함께하는 모던 JS 딥다이브 스터디 3차 💕

책 출처

타입 변환과 단축 평가

⚠️ 타입 변환은 기존 원시 값을 이용해 다른 타입의 새로운 원시 값을 생성하는 것.

  • 기존 원시 값은 변경되지 않는다.
    (애초에 원시타입은 변경불가능한 값(immutable value)이기 때문)
  • x + '' 표현식을 평가하기 위해 10을 바탕으로 '10'을 임시 생성 후
    10 + ''을 평가 해 '10'을 할당한다.

🧐 책에서는 '새 타입의 값을 만들어 단 한 번 사용하고 버린다'지만
만약 임시로 생성된 값과 평가될 값이 같다면 버려질까?

가설 1) 임시로 타입 변환된 값은 메모리에 저장되지 않고
임시값 + ''을 평가 한 결과만 메모리에 저장한다.

👉🏻 이럼 단 한 번만 사용하고 버릴 수 있음.
👀 계산을 하기 위해선 메모리에 저장이 돼야 하지 않나?

가설 2) 임시로 타입 변환된 값은 '10'으로 일단 메모리에 저장된 후
평가한 결과를 메모리에 저장할 때 기존 값의 메모리를 해제한다.

if) 임시값 + ''을 평가한 결과와 임시값이 같을 경우
기존에 임시값이 메모리에 있으므로 그대로 식별자와 연결한다.

👉🏻 이러면 단 한 번만 사용하고 버릴 수 없음.
👀 임시값을 단 한 번 사용하고 버린다면 메모리에 저장되었던 임시 값을
가비지 컬렉터가 적절한 시점(할당 되기 전)에 메모리에서 해제해야 함.

🍡 암묵적 타입 변환

에러 방지로 타입 강제 변환

문자열 타입으로 변환

표현식을 평가할 때 코드 문맥이 문자열로 표현되어야 할 경우.

상황: + 연산자를 사용할 때 피연산자가 하나라도 문자열일 경우.

Symbol() + '' // 타입 에러: 심볼 타입은 문자열로 바꿀 수 없습니다.
{} + '' // [object Object]
// 👉🏻 결과가 0으로 나온다면 코드블록 + '' 이므로 +0 으로 평가된 것
[10, 20] + '' // 10,20
(function(){}) + '' // function () { var $_$c = $_$wf(1); } 

[object Object]
Every object has a toString() method that is automatically called when the object is to be represented as a text value or when an object is referred to in a manner in which a string is expected
👉🏻 모든 object는 toString 메서드를 갖고 있고, object가 text value로 표현될 때나
문자열로 표현되야 할 때 자동으로 해당 메서드를 호출해 [object type] 형식으로 반환한다.

숫자 타입으로 변환

표현식을 평가할 때 코드 문맥이 숫자타입으로 표현되어야 할 경우.

  • 산술 연산
  • 비교 연산
  • 단항 연산
    + 단항 연산자: 피연산자가 숫자타입이 아니면 암묵적 숫자 타입 변환
+'string' // 
+'' // 
+null // 
+true // 
+'0' // 
+[] // 
+{} // 
+[10, 20] // 

불리언 타입으로 변환

truthy와 falsy
불리언 타입으로 평가되어야 할 값을 일컫음

truthy: true로 평가되어야 할 값
falsy: false로 평가되어야 할 값

⚠️ fasly 값

false

undefined

null

NaN

0, -0 ⭐️

'' // 빈 문자열

🍡 명시적 타입 변환

개발자가 의도를 가지고 명시적으로 타입을 변환하는 것.

  • 타입 캐스팅

    캐스팅 : 던지다 | 배역을 정하다 ✅

문자열 타입 변환

  1. String() 사용
  2. .toString() 사용
  3. 문자열 연결 연산자 (+) 사용
_ + ''

1 + '' // '1'
true + '' // 'true'

숫자 타입 변환

  1. Number() 사용
  1. parseInt, parseFloat() 사용
const mix = '100점 맞았습니다';
console.log(parseInt(mix)) // 100
console.log(parseFloat(mix)) // 100
console.log(parseFloat(null)) // NaN
  1. +단항 산술 연산자 사용
  2. * 산술 연산자 사용
'0' * 1; // 1
true * 1; // 1
false * 1; // 0
'' * 1 // 0
[] * 1 // 0
{} * 1 // NaN

불리언 타입 변환

  1. Boolean() 사용
  2. ! 부정 논리 연산자 두번 사용

🍡 타입 변환 주의사항 정리

숫자 타입 변환

+[] // 0
+{} // NaN
  • 빈 배열은 숫자타입 변환 시 0!!
    나머지 객체타입은 비어있더라도 NaN

불리언 타입 변환

false

undefined

null

NaN

0, -0

'' // 빈 문자열

[], {} 등 객체타입 다 true

🍡 단축 평가

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

논리곱, 논리합 연산자

  • 논리곱(&&) 연산자: falsy한 값을 찾아서 반환
    👉🏻 피연산자가 모두 truthy할 경우 맨 마지막 truthy값 반환

  • 논리합(||) 연산자: truthy한 값을 찾아서 반환
    👉🏻 피연산자가 모두 falsy할 경우 맨 마지막 falsy값 반환

// 논리곱(&&) 연산자
true && true // true
true && false // false
true && 'hello' // hello
false && 'hello' // false
'' && 'hello' // '' ⭐️
[] && 'hello' 'hello'

// 논리합(||) 연산자
true || true // true
true || false // true
false || true // true
true || 'hello' // true
false || 'hello' // hello
'' || 'hello' // 'hello'
[] || 'hello' // []

⭐️친 부분에서 알 수 있듯이 논리곱 연산자(&&)로 값 체크를 할 때
''(빈 문자열)도 falsy한 값으로 판단될 수 있다.

때문에 옵셔널 체이닝 연산자 or null 병합 연산자를 사용하는 것이 안전하다.

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

좌항의 피연산자가 null | undefined인 경우 undefined를 반환.
그렇지 않으면 우항의 프로퍼티 참조를 이어간다.

func?.(args)

obj?.prop

const obj = {
  prop1: 'hi',
  prop2: 'name',
  first: {
    second: 'second'
  };
};

console.log(obj?.first?.second) // 'second'
console.log(obj?.first?.third) // undefined

함수 호출과 옵셔널 체이닝

메서드를 호출할 때 옵셔널 체이닝을 사용할 경우,
에러발생 대신 undefined를 반환한다.

const someInterFace = {
	customMethod: () => 'this is customMethod'
}

console.log(someInterFace.customMethod?.()) // this is customMethod
console.log(someInterFace.customMethod1?.()) // undefined
console.log(someInterFace.customMethod1()) // ⚠️ 오류 발생

null 병합 연산자(??)와 옵셔널 체이닝

좌항의 피연산자가 null | undefined인 경우 우항의 피연산자를 반환,
아닐 경우 좌항의 피연산자를 반환.

👉🏻 옵셔널 체이닝을 사용한 후 undefined가 반환될 때
기본 값을 주기 위해 사용될 수 있다

const user = {
  name: "jeongs",
  details: { age: 25 }
};
console.log(user?.city ?? "Unknown city"); // Unknown city
console.log(user?.name ?? "Unknown name"); // jeongs
profile
💪🏻 아는 걸 설명할 줄 아는 개발자 되기

0개의 댓글