925 字
5 分钟
使用位运算管理类型或状态
前 言在许多场景,尤其前端组件库开发中,使用位运算管理 类型/状态 是一种非常高效和优雅的方式,特别适合处理”多状态共存” 或 “类型组合”。这种方式利用二进制位的独立性,通过位运算实现状态的组合、判断和修改,具有性能高、代码简洁、扩展性强的特点。
一、基本原理
TIP 用二进制的每一位来代表一个独立的状态/类型,然后通过位运算(与、或、非、异或、与非等)来实现状态的判断/组合/切换等操作
- 每个状态 / 类型用
2^n(即1 << n)表示,确保二进制中只有一位为1(互不干扰)。- 用一个数字(二进制)存储多个状态的组合(每一位代表该状态是否生效)。
- 通过位运算快速操作:
- 组合状态:
|(或运算,叠加状态)- 检查状态:
&(与运算,判断是否包含某状态)- 移除状态:
& ~(与非运算,清除某状态)- 切换状态:
^(异或运算,反转某状态)
二、简单示例
这里我们以一个Button组件状态管理场景举例:
1. 定义状态枚举
// 每个状态对应一个二进制位enum ButtonStatus { Disabled = 1 << 0, // 1 二进制: 0001 Loading = 1 << 1, // 2 二进制: 0010 Selected = 1 << 2, // 4 二进制: 0100 Highlight = 1 << 3 // 8 二进制: 1000}2. 状态操作方法
class Button { private status: number = 0
// 判断 hasStatus(target: ButtonStatus): boolean { return (this.status & target) !== 0 }
// 组合:可同时添加多个 addStatus(...states: ButtonStatus[]): void { states.forEach((state) => { this.status |= state }) }
// 删除:可同时移除多个 removeStatus(...states: ButtonStatus[]): void { states.forEach((state) => { this.status &= ~state }) }
// 切换: 存在则移除,不存在则添加 toggleStatus(state: ButtonStatus): void { this.status ^= state }}三、应用场景
除了上面举例的场景外,还有很多类似的场景都可以考虑使用,比如:
1. 权限管理
用位值表示不同权限(如查看、编辑、删除),用户的权限集合为多个位的组合,通过位运算快速判断是否有权限
enum Permission { View = 1 << 0, // 1 Edit = 1 << 1, // 2 Delete = 1 << 2, // 4 Admin = 1 << 3 // 8}
// 用户权限:可以查看和编辑const userPerms = Permission.View | Permission.Edit;
// 判断是否有权限删除const canDelete = (userPerms & Permission.Delete) !== 0; // false2.事件类型组合
enum EventType { Click = 1 << 0, // 点击 Hover = 1 << 1, // 悬浮 Focus = 1 << 2 // 聚焦}
// 监听「点击」和「聚焦」事件const listenEvents = EventType.Click | EventType.Focus;
// 触发事件时判断类型function handleEvent(type: EventType) { if (type & listenEvents) { console.log('处理点击'); }}3.特征标记
enum Feature { DarkMode = 1 << 0, // 深色模式 NewUI = 1 << 1, // 新UI Beta = 1 << 2 // beta功能}
// 为用户开启「深色模式」和「新UI」const userFeatures = Feature.DarkMode | Feature.NewUI;
// 检查是否开启新UIif (userFeatures & Feature.NewUI) { renderNewUI();}四、优缺点总结
适用场景 状态数量少(通常≤20 种)、状态间独立无依赖、需要频繁组合 / 检查状态的场景
优势
- 性能高效:位运算为底层操作,比数组 / 对象的遍历判断更快
- 代码简洁:一行位运算代替多行条件判断,减少冗余逻辑
- 扩展性强:新增状态只需添加一个位值,无需修改已有判断逻辑
- 内存友好:一个数字即可存储多个状态,比对象 / 数组更节省空间
不足
- 状态数量有限: 受限于整数位数
- 可读性较低
使用位运算管理类型或状态
https://blog.oceanh.top/posts/frontend/使用位运算管理类型或状态/