bigint不支持直接使用&、|等位运算符,因其会强制转为32位有符号整数导致高位截断;必须用.and()、.or()、.xor()等原生方法实现原子化权限校验,避免精度损失。

BigInt 本身不支持直接使用 JavaScript 的位逻辑运算符(如 &、|、^、~),但可通过显式转换和封装实现对超长权限掩码的原子化校验——关键在于用 and、or、xor、not 等 BigInt 原生方法替代传统运算符,并结合无符号右移模拟(因 >>> 不支持 BigInt)。
为什么不能直接用 & 等运算符校验 BigInt 权限掩码
JavaScript 中,所有位运算符会将操作数强制转为 32 位有符号整数(ToInt32),导致高位截断。例如:
0x10000000000000000n(即 2⁶⁴) & 0x1n → 实际计算的是 0 & 1 → 结果为 0,完全丢失原始语义。
因此,必须全程使用 BigInt 方法,避免隐式类型转换。
用 and / or / xor 实现原子化权限校验
BigInt 提供了 .and()、.or()、.xor() 方法,接受另一个 BigInt,返回新 BigInt,行为等价于对应位运算且无精度损失。
- 校验某权限位是否开启:用
userMask.and(permissionBit) !== 0n - 批量校验多个权限(“全包含”):
userMask.and(requiredMask) === requiredMask - 校验“至少一个启用”:
userMask.and(requiredMask) !== 0n - 剔除某权限:`userMask.and(~permissionBit)`(注意:
~不可用,需改用not+ 掩码)
安全处理取反与无符号右移
~ 和 >>/>>> 在 BigInt 上无效。需手动构造补码或位宽上下文:
- 模拟
~x(按位取反):若权限体系固定为n位,可用(1n ;更通用做法是用 <code>x.not(),但它返回二进制补码形式(负值),实际校验中应配合掩码使用 - 模拟无符号右移
x >>> k:先用x >> k(算术右移),再与(1n 按位与,确保高位补 0 - 推荐实践:权限系统设计时明确最大位宽(如 128 位),定义常量
MAX_MASK = (1n ,所有取反操作基于此上下文
封装原子化校验工具函数
将逻辑收敛为可复用、不可中断的纯函数,避免中间状态泄漏:
const hasPermission = (userMask, permissionBit) => userMask.and(permissionBit) !== 0n;
<p>const hasAllPermissions = (userMask, maskSet) => {
const combined = maskSet.reduce((acc, bit) => acc.or(bit), 0n);
return userMask.and(combined) === combined;
};</p><p>const withoutPermission = (userMask, permissionBit) =>
userMask.and((1n </p><p>这些函数输入输出均为 <code>BigInt</code>,无副作用,可安全用于并发鉴权或 WASM 边界交互。</p>










