925 字
5 分钟
使用位运算管理类型或状态
2025-09-05
无标签
前 言

在许多场景,尤其前端组件库开发中,使用位运算管理 类型/状态 是一种非常高效和优雅的方式,特别适合处理”多状态共存” 或 “类型组合”。这种方式利用二进制位的独立性,通过位运算实现状态的组合、判断和修改,具有性能高、代码简洁、扩展性强的特点。

一、基本原理#

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; // false

2.事件类型组合#

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;

// 检查是否开启新UI
if (userFeatures & Feature.NewUI) {
  renderNewUI();
}

四、优缺点总结#

适用场景

​ 状态数量少(通常≤20 种)、状态间独立无依赖、需要频繁组合 / 检查状态的场景

优势#

  • 性能高效:位运算为底层操作,比数组 / 对象的遍历判断更快
  • 代码简洁:一行位运算代替多行条件判断,减少冗余逻辑
  • 扩展性强:新增状态只需添加一个位值,无需修改已有判断逻辑
  • 内存友好:一个数字即可存储多个状态,比对象 / 数组更节省空间

不足#

  • 状态数量有限: 受限于整数位数
  • 可读性较低
使用位运算管理类型或状态
https://blog.oceanh.top/posts/frontend/使用位运算管理类型或状态/
作者
Ocean Han
发布于
2025-09-05
许可协议
CC BY-NC-SA 4.0
最后修改时间
2025-09-05 12:09:17