null 병합 (nullish coalescing) 자바스크립트 연산자

원본: 자바스크립트의 null 병합 연산자란?

null 병합 연산자(nullish coalescing operator)는 ES2020에서 도입된 자바스크립트의 새로운 논리 연산자입니다.

이 포스트에서는 이 연산자가 무엇이며 어떻게 작동하는지 알아보겠습니다.

자바스크립트에는 AND(&&), OR(||), NOT(!), Nullish Coalescing(??) 등의 연산자가 있습니다. null 병합 연산자는 널리쉬 연산자 라고도 부르고 이는 두 개의 피연산자 사이에 사용됩니다.

operand1 ?? operand2;

이 연산자를 이해하려면 “nullish”, “coalescing”, short-circuiting이 무엇을 의미하는지 알아야합니다.

nullish 값이란?

자바스크립트에서 nullish 값이란 nullundefined를 의미합니다.

이러한 값은 논리상 false에 해당하는 값이지만 보다 구체적으로 null로 구분합니다. 모든 nullfalse 이지만 모든 falsenull인 것은 아닙니다.

따라서 일반적인 논리 연산자가 true, false와 관련이 있다면 nullish 연산자는 null, undefined와 관련되어 있습니다.

coalescing의 의미

coalescing(병합)의 사전적 의미는 “둘 이상의 기구나 단체, 나라 따위가 하나로 합쳐짐” 이라는 뜻 입니다. 이러한 개념이 프로그래밍에서는 어떻게 적용될까요? 이는 여러 값을 모아서 하나의 값으로 만든다는 것을 의미하게 됩니다.

구체적으로 프로그래밍에서의 병합은 “값을 결합하는 것”을 의미하는 것이 아니라 “제공된 값에서 어떤 값을 만들어낼지 결정하는 것”에 관한 것 입니다.

포스트의 뒷 부분에서 이 개념이 어떻게 작동하는지 예제를 통해 알아보겠습니다.

short-circuiting

short-circuiting(전자회로 쇼트, 중단) 이라는 개념은 많은 프로그래밍 언어에 적용되어 있습니다. 이는 인터프리터가 boolean 관련 표현식을 실행할 때 관련 없는 부분을 건너뛰는 것과 같은 상황을 말합니다.

예를 들어, 인터프리터가 “나는 40 살이고 기술 분야에 종사하고 있습니다” 라는 표현식을 확인하는 경우, 내가 40 살이 아니라면 뒤의 종사하는 분야에 대해서는 확인하지 않고 false로 결론을 내립니다.

이 예에서 나이 확인 부분이 false 이기 때문에 short-circuiting이 발생하여 뒤의 조건을 확인하지 않고 넘어갔습니다. 이는 앞의 결과만으로 전체 표현식을 확인할 수 있기 때문에 시간, 전력, 리소스 등을 절약하기 위해 뒤의 확인을 하지 않고 넘어간 것 입니다.

null 병합 연산자

이제 이 연산자의 기본 사항을 살펴봤으니 이 연산자가 어떻게 작동하는지 알아보겠습니다.

표현식에서 이 연산자를 사용하면 첫 번째 피연산자(왼쪽)를 확인하여 해당 값이 null 인지 undefined 인지 확인합니다. 첫 번째 피연산자가 nullish 값이 아니라면 그냥 이 표현식을 리턴하고, nullish 값이라면 두 번째 피연산자(오른쪽)를 리턴합니다.

개발자 도구를 열어 다음의 간단한 예제를 테스트 해 보겠습니다:

function expression1() {
  return null;
}

const expression2 = 4 * 5;
const result = expression1() ?? expression2;

console.log(result);
nullish coalescing 예제

위의 예제에서 null을 리턴하는 expression1이 있고, 4 * 5 값을 리턴하는 expression2가 있습니다.

result 변수에는 null 병합 연산자를 사용하여 expression1()expression2를 피연산자로 사용했습니다.

첫 번째 피연산자는 null을 리턴합니다. null 병합 연산자는 첫 번째 피연산자가 nullish 임을 확인하고 두 번째 피연산자인 expression2를 리턴합니다.

이에 따라 result 변수를 console.log() 메소드를 통해 출력하면 expression2의 계산 값이 나타납니다.

다른 예제를 보겠습니다:

function expression1() {
  console.log("expression1");
  return false;
}

function expression2() {
  console.log("expression2");
  return "Dillion";
}

const result = expression1() ?? expression2();

console.log(result);
null 병합 연산자 예제

위의 예제에서는 false를 리턴하는 expression1Dillion을 리턴하는 expression2 가 있습니다. 이 코드를 실행하면 로그에 “expression1″이 찍히고 result의 값이 false인 것을 확인할 수 있습니다.

만일 첫 번째 피연산자가 nullish 값을 리턴했다면 두 번째 피연산자를 리턴했겠지만 이 경우 첫 번째 피연산자의 리턴 값이 nullish가 아닌 false 이므로 첫 번째 피연산자를 리턴했습니다.

또 확인해야 하는 부분은 콘솔 로그에 “expression2″가 찍히지 않았다는 점 입니다. 여기서는 첫 번째 피연산자의 결과에 의해 전체 표현식의 결과가 확인되어 short-circuiting이 발생했고 두 번째 피연산자는 전혀 실행되지 않았습니다.

null 병합 연산자 vs OR 연산자

null 병합 연산자와 OR 연산자는 몇 가지 비슷한 부분이 있지만 약간 다르게 작동합니다.

OR 연산자는 첫 번째 피연산자가 true 인지 확인합니다. 만일 첫 번째 연산자가 1 이면 리턴하고 그렇지 않으면 두 번째 피연산자를 리턴합니다. 하지만 null 병합 연산자는 첫 번째 피연산자가 nullish 인지 확인합니다.

OR 연산자의 예제는 다음과 같습니다:

const expression1 = "";
const expression2 = "Dillion";
const result = expression1 || expression2;

console.log(result);
OR 연산자 예제

위의 예제에서는 expression1false에 해당하는 값이기 때문에 expression2를 리턴했습니다. 만약 expression120 이었으면 expression1을 리턴하고 short-circuiting이 발생했을 것 입니다.

다음은 동일한 코드에 연산자만 바꿔서 실행해 보겠습니다:

const expression1 = "";
const expression2 = "Dillion";
const result = expression1 ?? expression2;

console.log(result);
null 병합 연산자 예제

결과 화면에서 볼 수 있듯이 result에는 expression1의 값이 할당되었습니다. 첫 번째 피연산자가 false에 해당하는 값이지만 nullish가 아니기 때문입니다.

null 병합 연산자 정리

null 병합 연산자는 잠재적인 nullish 값에 대해 기본 값을 선언해야할 경우 매우 유용합니다.

예를 들어 다음과 같이 API의 결과로 객체를 받았는데 객체의 속성이 옵셔널한 경우 다음과 같은 결과가 나타날 것 입니다:

const obj = {};

console.log(obj.type);
// undefined

여기에 null 병합 연산자를 사용한다면 nullish인 경우 기본 값을 제공할 수 있습니다.

const obj = {};

console.log(obj.type ?? "default");
// "default"

이 외에도 기본 값 할당 또는 세이프티 체크 등에 다양하게 사용할 수 있습니다.

관련 글