모던 JavaScript 튜토리얼 - null 병합 연산자 '??'

crewd·2021년 1월 10일
0
post-thumbnail

모던 자바스크립트 튜토리얼

ko.javascript.info

❗ 최근에 추가됨
스펙에 추가된 지 얼마 안 된 문법이다. 구식 브라우저는 폴리필이 필요하다.

null 병합 연산자(nullish coalescing operator) ??를 사용하면 짧은 문법으로 여러 피연산자 중 그 값이 '확정되어 있는' 변수를 찾을 수 있다.

a ?? b의 평가 결과는 다음과 같다.

  • anull도 아니고 undefined도 아니면 a
  • 그 외의 경우는 b

null 병합 연산자 ?? 없이 x = a ?? b와 동일한 동작을 하는 코드를 작성하면 다음과 같다.

x = ( a !== null && a !== undefined ) ? a : b;

코드 길이가 길어진다.
또 다른 예시를 살펴보자. firstName, lastName, nickName이란 변수에 사용자 이름이나 별명을 저장하는데, 사용자가 아무런 정보도 입력하지 않는 케이스도 허용한다고 해보겠다.

화면엔 세 변수 중, 값이 정해진 변수의 값을 출력하는데, 세 변수 모두 값이 정해지지 않았다면 "Anonymous"가 출력되도록 해보자.

이럴때 null 연산자 ??를 사용하면 값이 정해진 변수를 간편하게 찾아낼 수 있다.

let firstName = null;
let lastName = null;
let nickName = "Supercoder"

//null이나 undefined가 아닌 첫 번째 피연산자
alert(firstName ?? lastName ?? nickName ?? "Anonymous"); //Supercoder

'??'와 '||'의 차이

null 병합 연산자는 OR 연산자 ||와 상당히 유사해 보인다. 실제로 위 예시에서 ??||로 바꿔도 그 결과는 동일하다.

그런데 두 연산자 사이에는 중요한 차이점이 있다.

  • ||는 첫 번째 truthy 값을 반환한다.
  • ??는 첫 번째 정의된(defined) 값을 반환한다.

nullundefined, 숫자 0을 구분 지어 다뤄야 할 때 이 차이점은 매우 중요한 역할을 한다.

height = height ?? 100;

height에 값이 정의되지 않았다면 height에는 100이 할당된다.
이제 ??||을 비교해보자

let height = 0;

alert(height || 100); //100
alert(height ?? 100); // 0

height || 100height0을 할당했지만 0을 falsy 한 값으로 취급했기 때문에 null이나 undefined를 할당한 것과 동일하게 처리한다. 따라서 height || 100의 평가 결과는 100이다.

반면 height ?? 100의 평가 결과는 height가 정확하게 null이나 undefined일 경우에만 100이 된다. 예시에서는 height0이라는 결과를 할당 했기 때문에 0이 출력된다.

이런 특징 때문에 0이 할당될 수 있는 변수를 사용해 기능을 개발할 땐 || 보다 ??가 적합하다.

연산자 우선순위

??의 연산자 우선순위5로 꽤 낮다.
따라서 ??=?보다 먼저, 대부분의 연산자보다는 나중에 평가된다.
그렇기 때문에 복잡한 표현식 안에서 ??를 사용해 값을 하나 선택할 때는 괄호를 추가하는게 좋다.

let height = null;
let width = null;

// 괄호를 추가
let area = (height ?? 100) * (width ?? 50);

alert(area); // 5000

그렇지 않으면 *??보다 우선순위가 높기 때문에 *가 먼저 실행된다.

??엔 자바스크립트 언어에서 규정한 또 다른 제약사항이 있다.
안정성 관련 이슈때문에 ??&&||와 함께 사용하지 못한다.

let x = 1 && 2 ?? 3; // SyntaxError: Unexpected token '??'

이 제약에 대해서는 아직 논쟁이 많긴 하지만 사람들이 ||??로 바꾸기 시작하면서 만드는 실수를 방지하고자 명세서에 제약이 추가된 상황이다.

제약을 피하려면 괄호를 사용해주자.

let x = (1 && 2) ?? 3; // 제대로 동작

alert(x); // 2

요약

  • null 병합 연산자 ??를 사용하면 피연산자 중 '값이 할당된' 변수를 빠르게 찾을 수 있다.
    ??는 변수에 기본 값을 할당하는 용도로 사용할 수 있다.
// height가 null이나 undefined인 경우, 100을 할당
height = height ?? 100;
  • ??의 연산자 우선순위는 대다수의 연산자보다 낮고 ?=보다는 높다.
  • 괄호없이 ??||&&와 함께 사용하는 것은 금지되어있다.
profile
공부

0개의 댓글