
[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
섹션 1. 알아두어야 할 자바스크립트
ES2020에서 추가된 ??(널 병합 nullish coalescing) 연산자와 ?.(옵셔널 체이닝 optional chaining) 연산자이다.
이 연산자들을 사용하면 지저분한 코드들이 짧아지고 편해질 수 있다.
널 병합 연산자는 주로 ||(또는) 연사자 대용으로 사용된다.
falsy 값(0, '', false, NaN, null, undefined) 중 null과 undefined만 따로 구분한다.
const a = 0;
const b = a || 3; // || 연산자는 falsy 값이면 뒤로 넘어감
console.log(b); // 3

||(또는) 연산자는 falsy 값이면 뒤로 넘어가고 &&(그리고) 연산자는 true 값이 뒤로 넘어간다.
const c = 0;
const d = c ?? 3; // ?? 연산자는 null과 undefined일 때만 뒤로 넘어감
console.log(d); // 0

널 병합 연산자는 null과 undefined를 구분할 때 주로 사용한다.
let count = 0;
count || '123' // 123
count ?? '123' // 0

TypeError: Cannot read properties of null (reading 'd') 이나
TypeError: Cannot read properties of undefined (reading 'd')
와 같은 에러가 발생할 때 d가 null이나 undefined가 아니라 d 앞에 있는 c가 null이나 undefined 이다.
const a = {};
a.b; // a가 객체이므로 문제없음
const c = null;
try {
c.d;
} catch (e) {
console.error(e); // TypeError: Cannot read properties of null (reading 'd')
}

이 오류를 해결하기 위해 try/catch를 도배하는 것은 별로 좋지 않다. if 조건을 사용하여 객체가 있는지 확인할 수 있다.
if(c) {
c.d;
}

하지만 위 방법은 코드를 최소 세줄이상 차지하게되므로써 지저분해진다.
그래서 옵셔널 체이닝을 사용한다.
c?.d

c가 없으면 없는대로 나오고 c가 있으면 그 안에서 d를 찾는다.
함수도 같은 방법으로 실행할 수 있다.
try {
c.f();
} catch (e) {
console.error(e); // TypeError: Cannot read properties of null (reading 'f')
}
c?.f();

a.b.c.d.e
a?.b?.c?.d?.e
모든 객체에 옵셔널 체이닝 연산자를 쓰면 안전하긴 하나 가독성이 떨어지므로 진짜 긴가민가한 상황에서만 옵셔널 체이닝 연산자를 사용하는 것을 권장한다.
try {
c[0];
} catch (e) {
console.error(e); // TypeError: Cannot read properties of null (reading '0')
}
c?[0]; // 잘못된 문법
c?.[0];

c[0]에 옵셔널 체이닝 연산자를 사용하기 위해 c?[0]로 실행한다면 없는 문법이므로 오류가 발생한다. 옵셔널 체이닝을 위해서는 ?.로 사용해줘야 한다.
널 병합과 옵셔널 체이닝을 함께 사용하면 null과 undefined를 이중으로 확인하게 되면서 안정성이 높아지고 코드가 줄어드므로 적극적으로 사용하는 것을 추천한다.
c = null;
c?.[0] ?? '123' // '123'

d = [1,2,3];
d?.[0] ?? '123'

특히 옵셔널 체이닝을 사용하므로써 if문을 많이 줄일 수 있으므로 적극적으로 사용하는 것이 좋다.
📑 출처
- [개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지 (인프런/조현영)