카테고리 없음

[...].filter(Boolean)을 넣으면 어떤 일이 일어날까?

klm hyeon woo 2025. 5. 2. 18:05

코드 리팩토링을 진행하면서 filter 메서드는 보통 "~와 일치하는"의 키워드를 초점으로 항상 사용을 해왔던 것 같아요. 그러다 우연히 아래와 같은 문법을 보게 되었는데 명확한 값을 넣어준 것도 아니고, "자바스크립트에서 제공하는 Boolean을 넣었다고 값이 필터되어 나올까?" 에 대한 의문점이 생겼어요.

 

예를 들어 아래의 코드가 있다고 가정을 해보아요

const arr = [0, 1, false, 2, '', 3, null, undefined, NaN];
const filtered = arr.filter(Boolean);

console.log(filtered); // [1, 2, 3]

개발자가 유효한 값만 명시적으로 표시를 해주지 않았음에도 불구하고 [1, 2, 3] 이라는 유효한 값만 필터링된게 정말 신기하지 않나요?

filter()의 동작 방식

Array.prototype.filter는 이렇게 동작해요.

array.filter(callback);

배열 요소 하나하나를 callback 함수에 넣어서 true를 반환하는 값만 남기고, false를 반환하는 값은 버려요.

const result = arr.filter(item => Boolean(item));

본래는 아래와 같이 Boolean이라는 함수를 명시적으로 콜백 함수와 함께 사용을 할 수 있어요. 하지만 Boolean 자체가 함수이기 때문에 아래와 같이 줄일 수 있게 된거죠. 즉, Boolean 함수가 filter의 콜백 함수 역할을 하게 된거예요.

const result = arr.filter(Boolean);

Boolean은 무엇을 반환해요?

자바스크립트의 Boolean 함수는 주어진 값을 true · false로 바꿔주는 함수를 의미해요.

이를 filter 안에 삽입된 콜백함수로써 작동하는 과정들을 한번 풀어 작성해보면 아래와 같이 풀어쓸 수 있을 것 같아요.

Boolean(0);          // false
Boolean(1);          // true
Boolean('');         // false
Boolean('hello');    // true
Boolean(undefined);  // false
Boolean(null);       // false
Boolean([]);         // true

filter는 true를 반환하는 값만 남긴다고 했잖아요. filter에 적용을 하게 되면, falsy한 값은 걸러내는 효과를 볼 수 있어요.

보통 어디에 잘 쓰일 수 있을까요?

arr.filter(item => item !== null && item !== undefined && item !== '' && item !== false && item !== 0 && !Number.isNaN(item));

원래라면 배열에서 유효한 값을 찾으려면 이렇게 써야하거든요.. 참 많은 조건식이 들어가서 보기 힘든 것 같아요.

그래서 설명을 했던 것처럼 falsy한 값을 걸러내는데 비교적 간단한 문법으로 사용하고 싶을 때 바로 적용을 해볼 수 있을 것 같아요.

  • 배열에 undefined / null / 빈 문자열이 섞여있을 때 클린업 용도로써 사용을 할 수 있을 것 같아요.
const names = ['Alice', '', 'Bob', null, 'Charlie', undefined];
const validNames = names.filter(Boolean);
console.log(validNames); // ['Alice', 'Bob', 'Charlie']
  • 옵셔널 값들이 섞여있을 때 존재하는 값만을 추출할 때도 사용할 수 있을 것 같아요.
// js
const data = [user.name, user.nickname, user.displayName].filter(Boolean);
  • React에서는 JSX 조건부 렌더링을 진행할 때 key 없는 요소를 제거하는데 사용할 수 있을 것 같아요.
const items = [isA && <A />, isB && <B />, isC && <C />].filter(Boolean);