본문 바로가기
개발/자바스크립트

[자바스크립트] null 병합 연산자(nullish coalescing operator) ??에 대하여

by 핸디(Handy) 2021. 2. 28.

Let's study nullish coalescing operator(??)

기억하기론 ECMA2015인가 추가됐고, TypeScript에서는 엄청 최근에 추가된 Null 병합 연산자 ?? 에 대해 알아보고자 한다.

?? 연산자는 여러 피연산자들 중에 그 값이 '확정되어 있는 변수'를 찾을 수 있다.

코드로 예시를 보자. 

let test = undefined ?? null ?? "apple";
console.log(test); // apple

let test2 = undefined || null || "amazon";
console.log(test2); // amazon

??연산자 뿐만 아니라 || 연산자 또한 마지막에 있는 apple, amazon를 가져온다.

이것만 보면 굳이 필요할까 싶지만 내가 실제 경험한 상황을 보자

let getDefaultPercent = (ratio) => {
	let currentRatio = ratio || 5;
    return currentRatio+"%";
}
getDefaultPercent(10); // 10%
getDefaultPercent(0); // expect : 0%, real : 5%
getDefaultPercent(); // 5%

나는 기본 Pecent 값을 5%로 설정했다. 그래서 아무런 값을 넣지 않을 때는 5% 다른 경우에는 내가 원하는 값을 계산해서 주길 바랬다.

근데 문제를 0 를 넘길 때 발생했다. 0 또한 실제 값이지만 || 연산자에서는 falsy 값이기 때문에 없는 값으로 취급된다.

<Truthy와 Falsy 에 관해서 내가 간단히 정리해둔 글이 있다. 애매하다 싶으면 보고 오시길>

 

[자바스크립트] Truthy, Falsy 애매한 이놈들에 대해서

Falsy.. 우리 말로는 거짓 같은 값으로 불리는 놈입니다. boolean 문맥상으로 false로 평가받는 값이라는 의미입니다. 이와 반대로 Truthy 가 있습니다. Truthy '0', 'false', [], {}, funtion(){} Falsy undefine..

all-dev-kang.tistory.com

쨋든 나는 이러한 오류를 방지하게 위해 추가 코드를 작성했었다.

let getDefaultPercent = (ratio) => {
	let currentRatio;
	if(ratio === 0 ) {
    	currentRatio = 0;
    }else {
    	currentRatio = ratio || 5;
	}
    return currentRatio+"%";
}

getDefaultPercent(0); // expect : 0%, real : 0%

0을 위해선 코드가 귀찮게 추가됐다. 하지만 다른 방법이 없어서 일단은 이렇게 사용하고 있었는데 ?? 연산자에 대해 알게 되었다.

이제 ?? 연산자를 써서 리펙토링 해보자

let getDefaultPercent = (ratio) => {
	let currentRatio = ratio ?? 5; // <- 여기면 ??로 바꾸면 된다
    return currentRatio+"%";
}
getDefaultPercent(10); // 10%
getDefaultPercent(0); // 0%
getDefaultPercent(); // 5%

다시 코드가 간결해졌고 우리가 원하는 의도를 정확히 구현할 수 있게 되었다.

따라서 우리는 || 와 ?? 의 차이점을 알게 되었다.

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

그리고 별도로 안정성 이슈로 인해 || 와 ?? 는 동시에 쓰지 못한다. 컴파일러가 의도를 분명히 파악하지 못하는 경우가 생기기 때문이다.

true || false ?? "aa"
//Uncaught SyntaxError: Unexpected token '??'

하지만 괄호를 통해 묶어주면 사용이 가능해진다.

(true || false) ?? "aa" // true

 

요약 하지면 이젠 기본값을 설정하거나 의도한 값을 정할 때 || 대신 ??를 쓰자.

별도로 함수로 인자를 넘길 때 기본값을 주는 방법은 아래와 같이 추가로 생겼다.

let getDefaultPercent = (ratio = 5) => {
	let currentRatio = ratio;
    return currentRatio+"%";
}
getDefaultPercent(); // 5%

 

댓글