Logo

[ES2020] ?? 연산자 - Nullish Coalescing

nullish coalescing을 지원하기 위해서 ES2020에서 추가된 문법인 ?? 연산자에 대해서 알아보도록 하겠습니다.

|| 연산자를 통한 기본값 처리의 문제점

그동안 자바스크립트에서는 주로 || 연산자(logical OR)를 사용해서 기본값 처리를 해왔는데, 이 방법은 한 가지 맹점이 있었습니다.

간단한 예로, options 객체를 인자로 받는 다음 isEnabled 함수를 생각해보겠습니다.

function isEnabled(options) {
  return options.enabled || true;
}

의도했던 대로 enabled 속성값이 undefined이거나 null일 때, 기본값인 true를 리턴합니다.

> isEnabled({})
true
> isEnabled({enabled: null})
true

하지만 enabled 속성값이 false일 때도, 엉뚱하게 true가 리턴되는 것을 볼 수 있습니다. 😝

> isEnabled({enabled: false})
true

왜 이러한 오류가 발생하는 걸까요? 원인은 || 연산자는 자바스크립트에서 logical OR 구할 때 좌항이 falsy한 모든 경우에 우항을 선택하기 때문입니다. 자바스크립트에서는 undefinednull 뿐만 아니라 false, 0, "", NaN 등 다양한 값들이 falsy가 될 수 있습니다.

따라서 || 연산자로 기본값을 처리하면 falsy에 의존하는 코드가 되어 잘못 사용하면 다음과 같이 상황에 따라서 의도치 않은 결과를 얻을 수 있습니다.

> 0 || 10
10
> undefined || "unknown"
'unknown'

?? 연산자를 통한 견고한 기본값 처리

?? 연산자를 사용하면 nullish 즉, undefinednull에 대해서만 기본값 처리를 할 수 있습니다.

위에서 작성한 코드에서 || 연산자만 ?? 연산자로 대체해보겠습니다.

function isEnabled(options) {
  return options.enabled ?? true;
}

다시 테스트를 해보면 이번에는 예상대로 enabled 속성값이 false일 때는 기본값 적용되지 않는 것을 확인할 수 있습니다.

> isEnabled({})
true
> isEnabled({enabled: null})
true
> isEnabled({enabled: false})
false

?? 연산자는 다음과 같이 좌항이 undefinednull이 아닌 경우에만 우항을 선택하며, 그 외의 경우에는 항상 좌항을 선택합니다.

> null && 10
10
> 0 && 10
0
> undefined && "unknown"
undefined
> "" && "unknown"
''

?. 연산자와 함께 사용하기

?? 연산자는 ES2020에서 함께 도입된 ?. 연산자와 함께 사용하면 더욱 시너지를 발휘합니다. optional chaining을 위해 사용되는 ?. 연산자에 대한 내용은 관련 포스팅를 참고 바랍니다.

> user?.country ?? "Korea"
'Korea'

마치면서

2020년 현재 대부분의 최신 브라우저는 nullish coalescing을 지원하기 때문에 ?? 연산자를 사용할 수 있습니다. Node.js의 경우 버전 14부터 지원하며, 그 이전 버전에서는 Babel과 같은 트랜스파일러(transfiler)를 통해서 접해볼 수 있습니다.

nullish coalescing에 대한 좀 더 자세한 내용은 관련 MDN 공식 문서를 참고 바랍니다.