a ?? b
의 평가 결과는 다음과 같습니다.
x = a ?? b
와 동일한 동작을 하는 코드를 작성하면 다음과 같습니다.
x = (a !== null && a !== undefined) ? a : b;
또 다른 예시 NameOne, NameTwo, NameThree이란 변수에 사용자 이름을 저장하는데, 사용자가 아무런 정보도 입력하지 않는 케이스도 허용한다고 한다.
화면엔 세 변수 중 실제 값이 있는 변수의 값을 출력하는데, 세 변수 모두 값이 없다면 '익명의 사용자’가 출력되도록 해보자.
이럴 때 nullish 병합 연산자 ??를 사용하면 값이 정해진 변수를 간편하게 찾아낼 수 있습니다.
let NameOne = null;
let NameTwo = null;
let NameThree = "홍길동";
// null이나 undefined가 아닌 첫 번째 피연산자
alert(firstName ?? lastName ?? nickName ?? "익명의 사용자"); // 홍길동
--링크 삽입--
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