浅析TS枚举与位运算的结合

前言

近期笔者在读一些TS库的源码过程中发现枚举和位运算经常结合使用,而在平常项目中基本用不到这种写法,因此写篇短文记录下。

基础位运算符

先来看下JS/TS中提供的位运算符

运算符 用法 描述 示例(a = 5, b = 3)
& a & b 在 a,b 的位表示中,每一个对应的位都为 1 则返回 1,否则返回 0 5 & 3 → 0101 & 0011 = 0001 (1)
| a | b 在 a,b 的位表示中,每一个对应的位,只要有一个为 1 则返回 1,否则返回 0 5 | 3 → 0101 | 0011 = 0111 (7)
^ a ^ b 在 a,b 的位表示中,每一个对应的位,两个不相同则返回 1,相同则返回 0 5 ^ 3 → 0101 ^ 0011 = 0110 (6)
~ ~a 所有位取反 ~5 → ~0101 = 1010 (-6)
<< a << 1 将 a 向右移动指定位数,右边移入 0 5 << 1 → 0101 << 1 = 1010 (10)
>> -a >> 1 保留符号位向右移动 -5 >> 1 → 111..1011 >> 1 = 111..1101 (-3)
>>> -a >>> 1 忽略符号位向右移动(补 0) -5 >>> 1 → 2147483645

P.S. 上面示例中因排版数字的二进制格式只展示前4位, 实际上进行运算时都是32位有符号整数

结合TS枚举

通过位运算的操作去定义枚举,并代码中同样通过位运算符去实现判断逻辑。

TS 复制代码
enum Permission {
  Read = 1 << 0,    // 00000001
  Insert = 1 << 1,   // 00000010
  Delete = 1 << 2,  // 00000100
  Update = 1 << 3, // 00001000
  Admin = Read | Insert | Delete | Update // 00001111
}

上面我们定义了一个权限的枚举,接下来可以看下如何与位运算结合更方便我们实现权限判断的逻辑

TS 复制代码
const user = { roles: Permission.Read };

const doInsertOrUpdate = (roles: number) => {
    if (roles & (Permission.Insert | Permission.Update)) {
        console.log('执行插入或更新逻辑')
    } else {
        console.log('无权限')
    }
};

// 新增插入权限
// 00000001 | 00000010 = 00000011
user.roles |= Permission.Insert;

// 判断是否有插入或更新权限
// (00000010 | 00001000) = 00001010
// 00000011 & 00001010 = 00000010 = 2
// 输出:执行插入或更新逻辑
doInsertOrUpdate(user.roles);

// 重置插入及删除权限
// (00000010 | 00001000) = 00001010
// ~00001010 = 11110101
// 00000011 & 11110101 =  00000001
user.roles &= ~(Permission.Insert | Permission.Update); 

// 判断是否有插入或更新权限
// (00000010 | 00001000) = 00001010
// 00000001 & 00001010 = 00000000 = 0
// 输出:无权限
doInsertOrUpdate(user.roles);

优缺点分析

优点

  • 空间效率高:一个枚举的所有状态都可以压缩到一个数字去表示
  • 操作高效:位运算的性能通常优于其他逻辑操作
  • 组合灵活: 多个枚举间可以很方便组合,替换

缺点

  • 枚举数量存在上限:32位整数最多表示32种类型
  • 可读性差

总结

位运算与TS枚举的结合提供了一种高效的状态管理方式,特别适合需要处理大量组合状态的场景。虽然它牺牲了一定的可读性,但在性能和空间效率上的优势使其成为底层库和框架中的常见模式。在实际项目中,也能根据团队情况和具体需求权衡使用。

相关推荐
GuWenyue2 小时前
放弃云端API!一套React+WebGPU本地LLM方案,零数据上传、离线可用
前端·人工智能·前端框架
原则猫3 小时前
函数/变量提升
前端
独泪了无痕4 小时前
Vue3 Hooks使用实战解析
前端·vue.js
shawxlee5 小时前
vue3在public下封装config.js自定义配置动态数据,可在打包后直接修改,方便后端部署及后续维护
前端·javascript·经验分享·vue·团队开发·js·项目优化
用户059540174466 小时前
把记忆存储的回归测试从手工换成 Playwright + GitHub Actions,线上缺陷降低 80%
前端·css
触底反弹6 小时前
🚀 从 DOM0 级到 React 合成事件:前端事件监听的 20 年演进史
前端·react.js·面试
kyriewen6 小时前
我给前端项目的接口请求套了6层保护——才发现以前一直在裸奔
前端·javascript·面试
颜酱6 小时前
04 | 召回前置准备:搭好召回所需的四个数据库
前端·人工智能·后端
郝亚军7 小时前
如何安装webstorm、Node.js和vue CLI
前端·javascript·vue.js
IT_陈寒7 小时前
React的useEffect依赖项把我坑惨了
前端·人工智能·后端