Published on

nullish 병합 연산자

Authors

nullish 병합 연산자

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

a ?? b 의 평가 결과는 아래와 같다.

  • a가 null도 아니고 undefined도 아니면 a
  • 그 외의 경우에는 b

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

x = a !== null && a !== undefined ? a : b

아래의 예시를 살펴보자.

let firstName = null
let lastName = undefined
let nickName = 'zubetcha'

console.log(firstName ?? lastName ?? nickName ?? 'anonymous') // 'zubetcha'
console.log(lastName ?? firstName ?? 'anonymous' ?? nickName) // 'anonymous'
nullish example

첫 번째 console.log


  • firstName의 값은 null 이기 때문에 무시하고 그 다음에 있는 피연산자인 lastName의 값을 평가한다.
  • lastName의 값은 undefined 이기 때문에 무시하고 그 다음에 있는 피연산자인 nickName의 값을 평가한다.
  • nickName의 값은 zubetcha 이기 때문에 (null 이나 undefined이 아니기 때문에) 해당 값을 반환하고 그 다음에 있는 피연산자인 'anonymous' 는 평가하지 않는다.

두 번째 console.log


  • lastName의 값은 undefined 이기 때문에 무시하고 그 다음에 있는 피연산자인 firstName의 값을 평가한다.
  • firstName의 값은 null 이기 때문에 무시하고 그 다음에 있는 피연산자인 anonymous 를 평가한다.
  • 'anonymouse' 는 String 으로, null 이나 undefined가 아니기 때문에 nullish 병합 연산자는 anonymous를 반환하고 그 다음에 있는 피연산자인 nickName은 평가하지 않는다.

하지만 위와 같은 연산은 nullish 병합 연산자인 || 을 통해서도 동일한 값을 얻을 수 있다. 아래와 같이 ??|| 로 변경하여도 동일하게 'zubetcha'와 'anonymous'가 출력되는 것을 확인할 수 있다. 그렇다면 ??|| 에는 어떤 차이가 있을까?

console.log(firstName || lastName || nickName || 'anonymous') // 'zubetcha'
console.log(lastName || firstName || 'anonymous' || nickName) // 'anonymous'
nullish example

||(or 연산자) 와의 차이

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

??|| 의 차이는 숫자 0 등과 같이 false 로 간주하는 값을 어떻게 인식하여 처리하는지에 있다. || 는 숫자 0을 falsy한 값으로 취급하여 null 이나 undefined를 할당한 것과 동일하게 처리하지만, ?? 는 반드시 정확하게 null 이나 undefined를 가지고 있는 게 아니면 본래 할당되어 있는 값으로 온전히 평가된다.

자바스크립트에서는 기본적으로 false로 간주되는 값들이 있는데, 바로 숫자 0, ''(빈 문자열), NaN, null, undefined이다. or 연산자인 || 는 실제로 직접 할당된 값이 false가 아니더라도 false로 간주되는 값이 || 의 앞에 위치하면 해당 값을 false로 처리하여 반드시 || 의 뒤에 있는 값을 반환한다.

console.log(0 || nickName) // 'zubetcha'
console.log(0 || NaN) // NaN
console.log('' || 0) // 0
nullish example

변수에 falsy한 값을 할당한 후 각 연산자 ||?? 가 반환하는 값을 비교해보자.

💡 숫자 0 을 할당한 경우

let z = 0

console.log(z || 100) // 100
console.log(z ?? 100) // 0
nullish 0 example

💡 빈 문자열 '' 을 할당한 경우

let z = ''

console.log(z || 100) // 100
console.log(z ?? 100) //
nullish empty string example

💡 NaN 을 할당한 경우

let z = NaN

console.log(z || 100) // 100
console.log(z ?? 100) // NaN
nullish NaN example

💡 null 을 할당한 경우

let z = null

console.log(z || 100) // 100
console.log(z ?? 100) // 100
nullish null example

💡 undefined 를 할당한 경우

let z = undefined

console.log(z || 100) // 100
console.log(z ?? 100) // 100
nullish undefined example

각 연산자가 반환하는 값에서 알 수 있듯이, or 연산자 || 은 변수 z에 할당한 값이 falsy한 값인지, truthy한 값인지를 확인하여 falsy한 값이면 무조건 || 뒤에 위치한 값을 반환하고 있다. nullish 병합 연산자?? 는 변수 z에 할당한 값이 null 또는 undefined인지, 아닌지를 확인하여 ?? 앞에 위치한 값이 null 또는 undefined인 경우에만 ?? 뒤에 있는 값을 반환하고 있다.

단, nullish 병합 연산자 ?? 또한 or 연산자 || 와 같이 연산자의 앞에 위치한 값을 확인하므로 연산자 앞, 뒤에 모두 null 또는 undefined가 위치해 있더라도 연산자 앞에 있는 값이 null 또는 undefined이면 반드시 연산자 뒤에 있는 값을 반환한다.

console.log(null ?? undefined) // undefined
console.log(undefined ?? null) // null
nullish example