본문 바로가기
JavaScript & TypeScript/JavaScript

!! 연산자

by 감중에홍시 2023. 5. 25.

!! 연산자

회사에서 레거시 코드를 분석하던 중에 !!라는 생소한 코드를 보게 되었다.

(이 이상은 보안상 공개불가..ㅎㅎ)
처음 생각했을 때, 위 코드에서 existWebQuery 변수에는 dbInfo와 queryInfo가 둘 다 true일 경우, 

true 값이 저장되는 코드다라고 생각했다.
-> 어느정도 맞지만 엄밀히 말하면 아닙니다.

생각을 해보면 '논리 부정 연산자 '!'를 두 번 썼다면 부정의 부정이니 원래 dbInfo, queryInfo 값이 아닌가?' 라는 의문이 들었다.

그래도 선임자가 저 코드를 괜히 쓰지는 않았을테니 그 이유가 궁금하여 !! 연산자에 대해서 찾아보았다.

 

자바스크립트에서 '!!'는 boolean 값을 반환하도록 하는 간단한 방법 중에 하나이다. 

또한 boolean인 값으로 값을 강제로 변환하는데 사용된다.
이 연산자는 값이
truthy(참 값은 값, 0이 아닌 숫자, 빈 문자열이 아닌 문자열, 배열, 객체, 함수 등) 또는
falsy(거짓 같은 값, 0, 빈 문자열, null, undefined, NaN 등)인지 확인하기 위해 사용된다.

!! 연산자는 값을 강제로 boolean 값으로 변환하기 때문에 다른 연산자와 함께 사용되어 다양한 용도로 활용된다.

예를 들어 if 문에서 조건식으로 사용하면 해당 값이 truthy인지 falsy인지 확인할 수 있다.

const value = 'hello';
const boolValue = !!value;
console.log(boolValue); // true

const emptyValue = '';
const emptyBoolValue = !!emptyValue;
console.log(emptyBoolValue); // false

const numValue = 0;
const numBoolValue = !!numValue;
console.log(numBoolValue); // false

위의 코드에서,
value 변수는 truthy 한 값을 가지고 있으므로 !!value는 true를 반환한다.
emptyValue 변수는 falsy한 값을 가지므로 !!emptyValue는 false를 반환한다.
numValue 변수는 숫자 0이라는 값을 값을 가지지만 !! 연산자를 통해 변환해주면 boolean 값으로 변환되어 false를 반환한다.

 

Q. 그렇다면 이제 선임 개발자가 왜 코드를 저렇게 짰는지 생각을 해보자.

만약 어떤 값이 참인지 거짓인지를 판별하는 boolValue라는 변수가 있다고 생각해보자. 

이 변수에는 true와 false 두 가지 값만 들어가야 한다.

// expected: false
let boolValue = true && 0;
console.log(boolValue); // 0 
// 기대과 다르게 false가 아닌 그냥 숫자 0이 출력되는 모습

// expected: false
boolValue = true && !!0;
console.log(boolValue); // false

위와 같이 무엇인가의 진위판별(Boolean)를 하는 경우에 0과 같이 결과값이 애매할 수 있는 값을
!! 연산자를 사용하여 확실하게 논리연산자 True와 False로 바꿔줄 수 있다.

그리고 !! 연산자는 코드의 가독성과 의도를 명확하게 전달할 수 있는 장점이 있다.

코드를 읽는 사람으로 하여금 !! 연산자를 보면 해당 값이 명시적으로 논리 값으로 취급된다는 것을 알 수 있다.

따라서 코드의 의도를 분명히 전달하고 실수를 방지할 수 있다.

또한, !! 연산자는 변수의 값이 null, undefined, 0, NaN, false, 빈 문자열('') 등 falsy한 값인지 확인할 때 자주 사용된다.

이러한 값들을 명시적으로 논리 값으로 변환하기 위해 !! 연산자를 사용하는 것은 일반적인 프로그래밍 관례이다.

결론적으로, !! 연산자는 값의 논리적인 반대 값을 명시적으로 표현하고, 코드의 가독성과 의도를 개선하는데 도움을 준다.

 

따라서 선임 개발자 분은 로직을 짜는 데 있어서 확실하게 진위판별이 가능하도록 !! 연산자를 사용하지 않았을까 하는 생각이다.

 

같이 읽어보면 좋을 자료: 자바스크립트의 자료형. 뚱이와 광선맨 이야기