📚 이론정리/JS & TS

✏️ 옵셔널체이닝(Optional-chaining)과 널리쉬퀄리싱(Nullish-coalescing)

서카츄 2023. 11. 3. 21:54

 

 

 

옵셔널 체이닝(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