用 set 实现权限交集的核心是初始化阶段统一转为 set 实例,避免每次运算重复转换;通过遍历小集合调用 has() 实现高效交集;必要时用 weakmap 缓存固定组合结果。

用 Set 实现权限列表交集,核心是利用其 O(1) 查找性能 和原生 has() 方法,避免数组嵌套循环的 O(n×m) 开销。关键不在“怎么写”,而在“怎么组织数据”和“何时转换”。
权限数据统一转为 Set 实例
不要在每次求交时才转数组为 Set —— 那会重复消耗。初始化阶段就把用户权限、角色权限、接口白名单等,全部存为 Set:
- 用户 A 的权限:
new Set(['read:user', 'edit:post', 'delete:comment']) - 某接口所需权限:
new Set(['read:user', 'edit:post']) - 角色 B 的权限:
new Set(['read:user', 'read:post', 'export:data'])
后续所有交集运算都基于 Set,不碰原始数组。
手动遍历小集合做交集(推荐)
Set 没有内置交集方法,但用 for...of 遍历较小集合 + has() 判断,效率最高:
function intersect(setA, setB) {
const result = new Set();
const [smaller, larger] = setA.size
<p>这样时间复杂度是 <code>O(min(m, n))</code>,比双层循环快得多。实际场景中,接口所需权限通常远少于用户总权限,所以“小集合”往往是权限规则侧。</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill3430" title="Alibabacloud Sdk Client Initialization For Java"><img
src="https://img.php.cn/upload/skill/000/000/081/178955835420587.jpg" alt="Alibabacloud Sdk Client Initialization For Java" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill3430" title="Alibabacloud Sdk Client Initialization For Java" class="overflowclass">Alibabacloud Sdk Client Initialization For Java</a>
<p class="overflowclass">在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。</p>
</div>
<a rel="nofollow" href="/xiazai/skill3430" title="Alibabacloud Sdk Client Initialization For Java" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<h3>交集结果可直接用于鉴权判断</h3>
<p>不需要把交集转回数组——Set 本身就能高效判断是否满足最低权限:</p>
- 检查是否至少拥有某几个权限:
[...requiredPerms].every(p => userSet.has(p)) - 检查交集非空(即有重叠权限):
intersect(userSet, routePerms).size > 0 - 获取具体匹配项(如用于日志或调试):
Array.from(intersect(userSet, routePerms))
避免无意义的 Array.from() 或展开操作,除非业务明确需要数组形态。
配合 WeakMap 缓存高频交集结果
对固定组合(如“管理员角色 + 订单页权限”)可缓存结果,减少重复计算:
const intersectionCache = new WeakMap();
function getCachedIntersect(setA, setB) {
const key = setA; // 假设 setA 是稳定引用(如角色 Set)
if (!intersectionCache.has(key)) {
intersectionCache.set(key, intersect(setA, setB));
}
return intersectionCache.get(key);
}
注意:WeakMap 要求键是对象引用,适合缓存角色/模块等长期存在的 Set;用户权限动态变化则不宜缓存。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










