프론트엔드에서 여러 상태를 동시에 관리해야 하는 경우가 자주 있다.
예를 들어 사용자가 어떤 행동을 했는지, 특정 조건을 충족했는지를 모두 Boolean 값으로 관리하면 다음과 같은 코드가 된다.
const isMorning = true;
const isAfternoon = false;
const isEvening = true;
const isNotSmoked = true;
TypeScript
복사
이처럼 상태가 많아질수록 관리가 복잡해지고, 특정 조합을 검사하는 조건문도 길어진다.
이럴 때 비트마스크(bitmask)를 사용하면 훨씬 간결하고 효율적으로 상태를 표현할 수 있다.
비트마스크란?
비트마스크는 비트 단위로 상태를 저장하는 정수다.
각 비트(bit)는 0 또는 1 값을 가지며, 이진수의 각 자리에 의미를 부여할 수 있다.
예를 들어 아래처럼 각 상태를 하나의 비트로 정의할 수 있다.
enum RecordFlags {
MORNING = 1 << 0, // 0001
AFTERNOON = 1 << 1, // 0010
EVENING = 1 << 2, // 0100
NOT_SMOKED = 1 << 3, // 1000
}
TypeScript
복사
1 << 0은 0001, 1 << 1은 0010과 같다.
이제 여러 상태를 하나의 숫자로 합칠 수 있다.
상태 결합 (OR 연산)
비트마스크에서 여러 상태를 동시에 설정하려면 OR(|) 연산을 사용한다.
let state = RecordFlags.MORNING | RecordFlags.NOT_SMOKED;
TypeScript
복사
위 코드는 다음과 같은 비트를 만든다.
MORNING(0001) | NOT_SMOKED(1000) = 1001
Plain Text
복사
즉, state = 9이지만 이 숫자 하나에 ‘아침’과 ‘금연’이라는 두 상태가 함께 저장되어 있다.
상태 확인 (AND 연산)
특정 상태가 포함되어 있는지 확인하려면 AND(&) 연산을 사용한다.
if (state & RecordFlags.MORNING) {
console.log("아침 상태다");
}
if (state & RecordFlags.NOT_SMOKED) {
console.log("금연 상태다");
}
TypeScript
복사
state & RecordFlags.MORNING의 결과가 0이 아니라면, MORNING 상태가 활성화되어 있음을 의미한다.
상태 해제 (AND NOT 연산)
특정 상태를 제거하려면 **AND(&)와 NOT(~)**을 함께 사용한다.
state = state & ~RecordFlags.MORNING;
TypeScript
복사
이 코드는 MORNING 비트를 0으로 만든다.
예시: 금연 기록 상태 관리
예를 들어 금연 앱에서 하루 중 어떤 시간대에 금연했는지를 기록한다고 하자.
아침, 점심, 저녁 상태 중 금연한 시간대를 표시하고 싶다면 다음과 같이 표현할 수 있다.
enum RecordFlags {
GOAL = 1 << 0, // 00001
MORNING = 1 << 1, // 00010
AFTERNOON = 1 << 2, // 00100
EVENING = 1 << 3, // 01000
NOT_SMOKED = 1 << 4, // 10000
}
let state =
RecordFlags.MORNING |
RecordFlags.EVENING |
RecordFlags.NOT_SMOKED;
TypeScript
복사
이제 조건문으로 간단히 복합 상태를 판별할 수 있다.
// 아침, 점심, 저녁 중 하나라도 선택 + 금연 상태
const isNotSmokedToday =
(state & RecordFlags.NOT_SMOKED) &&
(state & (RecordFlags.MORNING | RecordFlags.AFTERNOON | RecordFlags.EVENING));
if (isNotSmokedToday) {
console.log("오늘 하루 금연 성공!");
}
TypeScript
복사
위 조건문은 아래처럼 자연어로 읽힌다.
“금연 상태이며, 아침·점심·저녁 중 하나라도 기록된 경우”
왜 비트마스크를 쓰는가
비트마스크의 장점은 다음과 같다.
1.
메모리 효율성 – Boolean 여러 개 대신 숫자 하나로 표현 가능하다.
2.
빠른 연산 – 비트 연산은 CPU 수준에서 즉시 계산된다.
3.
조합 상태 표현의 간결함 – 여러 상태를 한 번에 검사할 수 있다.
특히 enum으로 정의된 상태들이 많을 때, 객체보다 훨씬 효율적이다.
7. 디버깅 팁
비트마스크 상태를 숫자로 찍으면 알아보기 어렵기 때문에
toString(2)를 사용해 이진수로 출력하면 직관적으로 확인할 수 있다.
console.log(state.toString(2)); // 예: "11010"
TypeScript
복사
마무리
비트마스크는 낡은 기법처럼 보일 수 있지만, 여전히 게임 로직, 권한 시스템, 상태 플래그 관리 등에서 강력하게 쓰인다. 단순한 Boolean 플래그가 여러 개 겹치는 상황이라면 비트마스크로 상태를 통합해 관리할 수 있다.