JavaScript [null 병합 연산자 '??']
⚠ 이 문법은 추가한 지 얼마 안 된 문법입니다. 구식 브라우저에서 에러가 있을 수 있습니다.
null 병합 연산자 ?? 를 사용하면 짧은 문법으로 여러 피연산자 중 그 값이 확정되어있는 변수를 찾을 수 있습니다.
a ?? b 의 평가 결과는 다음과 같습니다.
- a 가 null 도 아니고 undefined도 아니면 a
- 그 외의 경우는 b
null 병합 연산자 ?? 없이 x = a ?? b 와 동일한 동작을 하는 코드를 작성하려면 다음과 같습니다.
x = (a !== null && a !== undefined) ? a : b;
비교, 논리 연산자로 null 병합 연산자를 표현하니 코드가 길어지는 것을 볼 수 있습니다.
예시를 보겠습니다. 변수에 이름이나 별명을 저장하는데, 사용자가 아무런 정보도 입력하지 않는 케이스도 허용한다고 합니다. 그리고 변수 값을 출력할 때 세 변수 모두 값이 없다면 "없음"이 출력되도록 해보겠습니다.
let first = null;
let second = null;
let third = 'jane';
// null이나 undefined가 아닌 첫 번째 피연산자
alert(first ?? second ?? third ?? '없음' ); // jane
?? 와 || 의 차이
null 병합 연산자와 OR 연산자 || 는 상당히 유사해 보입니다. 그러나 두 연산자 사이에는 중요한 차이점이 있습니다.
- || 는 첫 번째 true 값을 반환합니다.
- ?? 는 첫 번째 정의된 값을 반환합니다.
null 과 undefined, 숫자 0을 구분 지어 다뤄야 할 때 이 차이점은 매우 중요합니다.
let height = 0;
alert(height || 100); // 100
alert(height ?? 100); // 0
|| 는 0을 false로 변환하고 100은 true로 변환하기 때문에 100을 출력한다.
??에서는 둘 다 값을 가지고 있기 때문에 첫 번째 값인 0을 출력한다.
연산자 우선순위
??의 연산자 우선순위는 5로 꽤 낮습니다.
따라서 ??는 = 와 ? 보다는 먼저, 대부분의 연산자보다는 나중에 평가됩니다.
그렇기 때문에 ??를 사용할 때는 괄호를 사용하는 것이 좋습니다.
let height = null;
let width = null;
// 괄호를 추가!
let area = (height ?? 100) * (width ?? 50);
alert(area); // 5000
위 코드의 경우 *가 ??보다 우선순위가 높기 때문에 *가 먼저 실행됩니다.
그리고 ??에는 또다른 제약사항이 있습니다.
안정성 관련 이슈 때문에 ??는 &&나 ||와 함께 사용하지 못합니다.
이 제약은 사람들이 ||를 ??로 바꾸기 시작하면서 만드는 실수를 방지하고자 명세서에 제약이 추가된 상황입니다.
제약을 피하고 싶다면 괄호를 사용해주세요
let x = (1 && 2) ?? 3; // 제대로 동작합니다.
alert(x); // 2
* 요약 *
- null 병합 연산자 ??는 할당된 변수를 찾아냅니다
- ?? 의 우선순위는 대다수의 연산자보다 낮고 ? 와 = 보다는 높습니다.
- 괄호 없이 ?? 를 || 나 &&와 함께 사용하는 것은 금지되어있습니다.
실습
경품 행사 중 당첨자가 오지 않으면 다음 사람이 받게 됩니다.
1. jane / 2. ban / 3. loan / 4. kane
이들 중 kane만 왔을 때 ?? 를 이용하여 kane이 출력되도록 만들어보세요.
let jane = null
let ban = null
let loan = null
let kane = 'kane'
let winner = ( jane ?? ban ?? loan ?? kane )
alert(winner)