✏️ 옵셔널체이닝(Optional-chaining)과 널리쉬퀄리싱(Nullish-coalescing)
옵셔널 체이닝(Optional-chaining)
옵셔널 체이닝은 `?` 을 사용하면 프로퍼티가 없는 중첩 객체를 에러 없이 안전하게 접근할 수 있다.
예를 들어서 우리가 비동기 데이터 통신을 한다고 가정해보자,
자바스크립트가 한줄 한줄씩 실행되는데
const { data } = useQuery(PRODUCT_LIST);
console.log(data);
return (
<div>
{data.fetchProfile.title}
</div>
);
코드가 이렇게 있다고 가정해보면, console.log에는 데이터가 들어오는데
return 영역에서는 에러가 뜬다.
그 이유는 비동기 통신을 하는데 백엔드에서 데이터가 가져오기 전에 아래가 먼저 실행이 되어버려서 오류가 뜨는 것이다.
그래서 해결 방안으로는
{data && data.fetchProfile.title}
&& 연산자를 사용하여 데이터가 있으면? 오른쪽을 띄워줘! 라고 하는데,
항상 data를 붙여서 사용하면 가독성이 떨어지기 때문에 `?` 을 붙여서 옵셔널체이닝을 사용한다.
{data && data.fetchProfile.title}
{data?.fetchProfile.title}
두개 코드는 같은 내용이다.
예시
true && "안녕하세요"
→ 안녕하세요
false && "안녕하세요"
→ false
10 && "안녕하세요"
→ 안녕하세요
0 && "안녕하세요"
→ 0
널리쉬퀄리싱(Nullish-coalescing)
널리쉬퀄리싱은 `null`이나 `undefined`일때 보는 것이다.
`??` 를 사용하면 짧은 문법으로 그 값이 `확정되어있는` 변수를 찾을 수 있다.
참, 거짓은 의미가 없다.
a가 null도 아니고 undefined도 아니면 a
그 외의 경우는 b
0
""
false
null
undefined
NaN
'??'와 '||'의 차이
nullish 병합 연산자는 OR 연산자 ||와 상당히 유사해 보이지만
그런데 두 연산자 사이에는 중요한 차이점이 있다.
null과 undefined, 숫자 0을 구분 지어 다뤄야 할 때 이 차이점은 매우 중요한 역할을 한다.
let firstName = null;
let lastName = null;
let nickName = "바이올렛";
// null이나 undefined가 아닌 첫 번째 피연산자
alert(firstName ?? lastName ?? nickName ?? "익명의 사용자"); // 바이올렛
예시
height = height ?? 100;
height에 값이 정의되지 않은경우 height엔 100이 할당된다.
이제 ??와 ||을 비교해보자.
let height = 0;
alert(height || 100); // 100
alert(height ?? 100); // 0
`height || 100`은 height에 0을 할당했지만
0을 거짓(falsy) 값으로 취급했기 때문에 null이나 undefined를 할당한 것과 동일하게 처리한다.
따라서 height || 100의 평가 결과는 100이다.
반면 `height ?? 100`의 결과는 height가 정확하게 null이나 undefined일 경우에만 100이 된다.
예시에선 height에 0이라는 값을 할당했기 때문에 얼럿창엔 0이 출력된다.
이런 특징 때문에 높이처럼 0이 할당될 수 있는 변수를 사용해 기능을 개발할 때는 `||`보다 `??`가 적합하다.
연산자 우선순위
`??` 의 연산자 우선순위는 `5`로 꽤 낮다.
따라서 `??` 는 `=`와 `?`보다는 먼저, 대부분의 연산자보다는 나중에 평가된다.
그렇기 때문에 복잡한 표현식 안에서 `??` 를 사용하여 값을 하나 선택할 때는 괄호를 추가하는 것이 좋다.
let height = null;
let width = null;
// 괄호를 추가!
let area = (height ?? 100) * (width ?? 50);
alert(area); // 5000
그렇지 않으면 *가 ??보다 우선순위가 높기 때문에 *가 먼저 실행된다.
결국엔 아래 예시처럼 동작한다.
// 원치 않는 결과
let area = height ?? (100 * width) ?? 50;
`??`엔 자바스크립트 언어에서 규정한 또 다른 제약사항이 있는데
안정성 관련 이슈 때문에 `??`는 `&&`나 `||`와 함께 사용하지 못한다.
아래 예시를 실행하면 문법 에러가 발생한다.
let x = 1 && 2 ?? 3; // SyntaxError: Unexpected token '??'
let x = (1 && 2) ?? 3; // 제대로 동작합니다.
alert(x); // 2
제약을 피하려면 괄호를 사용해줘야 한다.
요약
nullish 병합 연산자 `??`를 사용하면 피연산자 중 `값이 할당된` 변수를 빠르게 찾을 수 있다.
`??`는 변수에 기본값을 할당하는 용도로 사용할 수 있다.
// height가 null이나 undefined인 경우, 100을 할당
height = height ?? 100;
`??`의 연산자 우선순위는 대다수의 연산자보다 낮고 `?`와 `=` 보다는 높다.
괄호 없이 `??`를 `||`나 `&&`와 함께 사용하는 것은 `금지`되어 있다.
연습
data ?? data.fetchProfile
비어있으면? 오른쪽 꺼 실행해줘!
data && data.fetchProfile
참이면 오른쪽꺼 실행해줘!
data || data.fetchProfile
거짓이면? 오른쪽 꺼 실행해줘
0 ?? "사탕"
→ 0
undefined ?? "사탕"
→ 사탕
null ?? "사탕"
→ 사탕
Docs
Optional chaining - JavaScript | MDN
optional chaining 연산자 (?.) 는 체인의 각 참조가 유효한지 명시적으로 검증하지 않고, 연결된 객체 체인 내에 깊숙이 위치한 속성 값을 읽을 수 있다.
developer.mozilla.org
옵셔널 체이닝 '?.'
ko.javascript.info
nullish 병합 연산자 '??'
ko.javascript.info