notes
09장. 타입 변환과 단축 평가
모던 JS Deep Dive — 타입 변환과 단축 평가 핵심 정리.
참고: 이웅모 《모던 자바스크립트 Deep Dive》 9장 · [MDN Type coercion](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#type_coercion) · [MDN Nullish coalescing](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing)
== 한 번에 타입이 바뀌고, ||로 기본값을 넣다 0이 사라졌다.
타입 변환은 암묵(엔진이) 과 명시(내가) 로 나눈다. 단축 평가·옵셔널·null 병합은 “값 없을 때” 실무 도구다.
flowchart TB
V[값] --> IMP[암묵 변환]
V --> EXP[명시 변환]
IMP --> STR[문자열 문맥]
IMP --> NUM[숫자 문맥]
IMP --> BOOL[불리언 문맥]
SHORT[단축 평가 || &&] --> BOOL
NULLISH[??] --> NULLISH2[null/undefined만]
9.1 타입 변환이란?
기존 값을 다른 타입의 값으로 만드는 것. 원본 변수를 바꾸기보다 연산 과정에서 임시 값이 생기는 그림이 많다.
9.2 암묵적 변환
문자열 문맥
+에 문자열이 있으면 연결 쪽으로 기울기 쉽다.
console.log(1 + '2'); // '12'
console.log('1' + 2 + 3); // '123'
숫자 문맥
산술·비교 등.
console.log(1 - '2'); // -1
console.log('6' * '2'); // 12
console.log(+'10'); // 10
불리언 문맥
if, &&, ||, ! — Truthy/Falsy.
Falsy: false, 0, -0, 0n, '', null, undefined, NaN.
if ('') console.log('no');
if ([]) console.log('yes array'); // 빈 배열 truthy
9.3 명시적 변환
String(1);
(1).toString();
Number('1');
parseInt('1px', 10);
Boolean(1);
!!value;
의도를 드러낼 때는 명시를 선호.
9.4 단축 평가
&& / ||
console.log('a' && 'b'); // 'b'
console.log('' || 'default'); // 'default'
console.log(0 || 10); // 10 — 0이 유효값이면 버그
옵셔널 체이닝 ?.
const user = { profile: { name: '민섭' } };
console.log(user.profile?.name);
console.log(user.address?.city); // undefined — TypeError 대신
console.log(user.methods?.save?.());
null 병합 ??
null/undefined만 대체. 0/'' 유지.
console.log(0 ?? 10); // 0
console.log(null ?? 10); // 10
console.log(0 || 10); // 10
예제
function readPort(env) {
return Number(env.PORT ?? 3000);
}
function label(name) {
return name?.trim() || 'anonymous';
}
// 느슨한 비교 지뢰
console.log('' == 0); // true
console.log('' === 0); // false
헷갈리던 장면 / 함정
- || 기본값에 0/'' 필요
- == 사용
- [] truthy / '' falsy
- ?. 과용으로 버그 숨김
- ??와 || 혼동
표
질문 → 자답
Q. 암묵 변환을 없앨 수 있나? A. 완전히는 어렵다. 줄이고, 문맥을 명시하고, ===와 ??를 쓴다.
Q. ?. 왼쪽이 null이면? A. 표현식 전체가 undefined. 단락 평가.
웹 보강 메모
MDN equality · nullish · optional chaining. ESLint eqeqeq, no-constant-binary-expression 확인.
실무로 바로
- 비교: ===
- 기본값: ??
- 깊은 접근: ?.
- 폼 숫자: Number + isFinite
여기서 잠깐 💁♂️
다음 객체 장과 맞물려 “빈 객체/빈 배열이 truthy”가 다시 등장한다.
보강 — 객체/배열 ToPrimitive
객체가 문자열·숫자로 갈 때 toString/valueOf/Symbol.toPrimitive 경로. 날짜 +date가 숫자가 되는 이유.
const obj = {
[Symbol.toPrimitive](hint) {
if (hint === 'number') return 1;
return 'obj';
},
};
console.log(+obj, `${obj}`);
보강 — 단축 평가로 가드
user && user.save && user.save();
user?.save?.();
후자가 읽기 쉽다.
연습 체크리스트
- [ ] 핵심 표만 다시 그리기
- [ ] 함정 예제를 콘솔에서 재현
- [ ] MDN 링크 한 번씩 훑기
- [ ] 실무 코드에서 같은 패턴 검색
- [ ] 관련 장(앞뒤) 한 줄로 연결
일기 보강 — 헷갈림 → 찾아봄 → 정리
처음에 용어가 추상적으로 들렸다. 책을 덮고 한 줄 정의를 내 말로 다시 쓰고, 예제를 최소 세 개 쳐 보니 문제 유형이 보이기 시작했다. “외운 문장”이 아니라 “다시 설명 가능한 문장”이 남을 때까지 표를 줄였다 늘렸다.
추가 예제 블록
// 실험 1 — 기대 vs 실제를 주석으로 남긴다
console.log('실험');
// 실험 2 — 경계값
console.log('경계');
// 실험 3 — 실무 형태
function demo() { return true; }
console.log(demo());
웹·스펙 메모
MDN과 ECMA-262 용어가 다를 수 있다. 노트에는 내가 디버깅에 쓰는 말을 우선 적고, 면접용 키워드를 괄호로 병기한다. 원문 복붙 없이 “왜 이렇게 동작하나”만 남긴다.
실무 적용 한 스푼
PR 리뷰 때 이 장 키워드가 보이면 체크리스트를 붙인다. 버그 리포트에는 재현 코드와 기대/실제를 한 쌍으로 적는다. 팀 컨벤션이 없으면 이 노트 표를 초안으로 제안한다.
연습 체크리스트
- [ ] 핵심 표만 다시 그리기
- [ ] 함정 예제를 콘솔에서 재현
- [ ] MDN 링크 한 번씩 훑기
- [ ] 실무 코드에서 같은 패턴 검색
- [ ] 관련 장(앞뒤) 한 줄로 연결
일기 보강 — 헷갈림 → 찾아봄 → 정리
처음에 용어가 추상적으로 들렸다. 책을 덮고 한 줄 정의를 내 말로 다시 쓰고, 예제를 최소 세 개 쳐 보니 문제 유형이 보이기 시작했다. “외운 문장”이 아니라 “다시 설명 가능한 문장”이 남을 때까지 표를 줄였다 늘렸다.
추가 예제 블록
// 실험 1 — 기대 vs 실제를 주석으로 남긴다
console.log('실험');
// 실험 2 — 경계값
console.log('경계');
// 실험 3 — 실무 형태
function demo() { return true; }
console.log(demo());
웹·스펙 메모
MDN과 ECMA-262 용어가 다를 수 있다. 노트에는 내가 디버깅에 쓰는 말을 우선 적고, 면접용 키워드를 괄호로 병기한다. 원문 복붙 없이 “왜 이렇게 동작하나”만 남긴다.
실무 적용 한 스푼
PR 리뷰 때 이 장 키워드가 보이면 체크리스트를 붙인다. 버그 리포트에는 재현 코드와 기대/실제를 한 쌍으로 적는다. 팀 컨벤션이 없으면 이 노트 표를 초안으로 제안한다.
연습 체크리스트
- [ ] 핵심 표만 다시 그리기
- [ ] 함정 예제를 콘솔에서 재현
- [ ] MDN 링크 한 번씩 훑기
- [ ] 실무 코드에서 같은 패턴 검색
- [ ] 관련 장(앞뒤) 한 줄로 연결
일기 보강 — 헷갈림 → 찾아봄 → 정리
처음에 용어가 추상적으로 들렸다. 책을 덮고 한 줄 정의를 내 말로 다시 쓰고, 예제를 최소 세 개 쳐 보니 문제 유형이 보이기 시작했다. “외운 문장”이 아니라 “다시 설명 가능한 문장”이 남을 때까지 표를 줄였다 늘렸다.
추가 예제 블록
// 실험 1 — 기대 vs 실제를 주석으로 남긴다
console.log('실험');
// 실험 2 — 경계값
console.log('경계');
// 실험 3 — 실무 형태
function demo() { return true; }
console.log(demo());
웹·스펙 메모
MDN과 ECMA-262 용어가 다를 수 있다. 노트에는 내가 디버깅에 쓰는 말을 우선 적고, 면접용 키워드를 괄호로 병기한다. 원문 복붙 없이 “왜 이렇게 동작하나”만 남긴다.
실무 적용 한 스푼
PR 리뷰 때 이 장 키워드가 보이면 체크리스트를 붙인다. 버그 리포트에는 재현 코드와 기대/실제를 한 쌍으로 적는다. 팀 컨벤션이 없으면 이 노트 표를 초안으로 제안한다.