null 병합 연산자 ( nullish coalescing operator ) [ ?? ] 를 사용하면
여러 피연산자 중 그 값이 ‘ 확정되어있는 ’ 변수를 짧은 문법으로도 찾을 수 있다.
null 병합 연산자 [ ?? ] 를 사용하지 않고 만든
x = a ?? b와 동일하게 동작하는 코드는 다음과 같다.
x = (a !== null && a !== undefined) ? a : b;
길이가 길어진다.
firstName, lastName, nickName 이란 변수가 있는데 이 값들은 모두 옵션 값이라 한 후,
실제 값이 들어있는 변수를 찾고 그 값을 보여줘 본다. (모든 변수에 값이 없다면 익명을 출력).
let firstName = null; let lastName = null; let nickName = "바이올렛"; // null 이나 undefined 가 아닌 첫 번째 피연산자 alert(firstName ?? lastName ?? nickName ?? "익명"); // 바이올렛
null 병합 연산자는 OR 연산자 || 와 상당히 유사해 보인다.
실제로 위 예시에서 ?? 를 || 로 바꿔도 그 결과는 동일하다.
null 과 undefined, 숫자 0을 구분 지어 다뤄야 할 때 이 차이점은 매우 중요한 역할을 한다.
height = height ?? 100;
height 에 값을 정의하지 않은 상태라면 height엔 100이 할당된다.
그런데 height에 0이 할당된 상태라면 값이 바뀌지 않고 그대로 남아있다.
let height = 0; alert(height || 100); // 100 alert(height ?? 100); // 0
height || 100 은 height 에 0 을 할당했지만 0 을 falsy 한 값으로 취급했기 때문에
null 이나 undefined 를 할당한 것과 동일하게 처리한다.
높이에 0 을 할당하는 것과 유사한 유스케이스에선 [ || ]는 부정확한 결과를 일으킬 수 있다.
대신 height ?? 100 은 height 가
정확히 null 이나 undefined 일때만 height에 100을 할당한다.
[ ?? ] 의 연산자 우선순위는 7로 꽤 낮다.
대부분의 연산자보다 우선순위가 낮고, [ = ] 와 [ ? ] 보다는 조금 높다.
따라서 복잡한 표현식 안에서 [ ?? ] 를 사용할 땐 괄호를 추가해주는 게 좋다.
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