edited-image.png

!!란 무엇인가

!!는 JavaScript의 별도 연산자가 아니라, 논리 NOT 연산자(!)를 두 번 연속 사용한 것이다. 어떤 값이든 Boolean 타입으로 명시적 변환하는 관용적 패턴이다.

!!value
// 동일한 동작
Boolean(value)

동작 원리

두 단계로 나뉜다.

const name = "hello"

!name   // 1단계: truthy → false
!!name  // 2단계: false → true
  1. 첫 번째 ! — 값을 Boolean으로 변환한 뒤 반전
  2. 두 번째 ! — 다시 반전하여 원래 의미의 Boolean 값으로 복원

Falsy와 Truthy 값 정리

JavaScript에서 falsy로 평가되는 값은 7가지뿐이다.

!!false      // false
!!0          // false
!!-0         // false
!!0n         // false (BigInt)
!!""         // false
!!null       // false
!!undefined  // false
!!NaN        // false

이 외의 모든 값은 truthy다.

!!1          // true
!!"hello"    // true
!![]         // true  (빈 배열도 truthy)
!!{}         // true  (빈 객체도 truthy)
!!-1         // true
!!" "        // true  (공백 문자열도 truthy)

왜 사용하는가

1. 타입을 Boolean으로 확정

API 응답이나 변수의 타입이 불확실할 때, 확실한 true/false로 변환한다.

function isLoggedIn(user) {
  return !!user  // user 객체가 있으면 true, null/undefined면 false
}

return user로 하면 객체 자체가 반환되지만, return !!user는 반드시 Boolean이 반환된다.

2. 조건 저장

조건 결과를 변수에 저장할 때 원본 값이 아닌 Boolean으로 저장한다.

const hasItems = !!list.length
const isValid = !!inputValue.trim()
const isEnabled = !!config?.feature?.enabled

3. 비교 연산에서 의도 명확화

// 의도가 불분명
if (array.length) { ... }

// Boolean임을 명시
if (!!array.length) { ... }

// 가장 명확한 방식
if (array.length > 0) { ... }

4. React 등에서 렌더링 방지

React에서 0은 falsy지만 화면에 렌더링된다. !!로 Boolean 변환하면 이를 방지할 수 있다.

// 문제: items가 빈 배열이면 0이 화면에 출력됨
{items.length && <List items={items} />}

// 해결: Boolean으로 변환
{!!items.length && <List items={items} />}

!! vs Boolean()

둘은 결과가 동일하다.

!!value === Boolean(value)  // 항상 true

비교 항목!!Boolean()가독성익숙한 사람에게 간결의도가 명확길이짧다길다성능미미한 차이미미한 차이

팀 컨벤션에 따라 선택하면 된다.

실무 사용 예시

// 환경변수 존재 여부
const isProduction = !!process.env.PRODUCTION

// 옵셔널 체이닝과 함께
const hasPermission = !!user?.roles?.includes('admin')

// 필터링
const activeUsers = users.filter(u => !!u.lastLoginAt)

// TypeScript에서 타입 가드와 함께
const validItems = items.filter((item): item is Item => !!item)

정리

  • !!어떤 값이든 Boolean으로 변환하는 패턴이다
  • Boolean() 함수와 동일한 결과를 더 짧게 쓴 것이다
  • 값의 존재 여부를 true/false로 확정할 때 사용한다
  • 빈 배열 []과 빈 객체 {}는 truthy라는 점에 주의한다