用 Set 过滤黑名单用户标识,核心是将标识存入 Set 后用 has() 一次性判断是否命中,平均查找时间 O(1),比数组 includes() 更快、比对象键更安全轻量。

用 Set 过滤黑名单用户标识,核心是把标识(如用户 ID、手机号、设备号)存进 Set,再用 has() 一次性判断是否命中——平均查找时间仅 O(1),比数组 includes() 快得多,也比对象键更安全轻量。
初始化黑名单 Set
把原始黑名单数据一次性转为 Set,自动去重,避免后续重复创建:
- 直接传入数组:
const blackSet = new Set(['u1001', 'u1002', 'admin']) - 从后端加载后立即转换:
fetch('/api/blacklist').then(r => r.json()).then(list => blackSet = new Set(list)) - 注意类型统一:后端返回字符串,就别混入数字;
'123'和123在 Set 中视为不同值 - 若需忽略大小写或空格,先标准化:
new Set(rawList.map(s => s.trim().toLowerCase()))
单个标识快速校验
每次收到请求或用户操作时,一行代码即可拦截:
if (blackSet.has(userId)) throw new Error('Blocked')- 用于登录校验、消息发送前检查、API 权限拦截等场景
- 不建议在循环里反复新建 Set,应复用同一实例
批量过滤用户列表
对用户数组做整体清洗,保留非黑名单成员:
const validUsers = users.filter(u => !blackSet.has(u.id))- 支持链式处理,比如
.filter(...).map(...).slice(0, 20) - 若需按多字段组合判断(如
userId + action),可构造复合键:blackSet.has(`${u.id}-${u.action}`)
运行时动态更新
黑名单常需热更新,Set 天然支持增删,无需重建整个结构:
- 新增:
blackSet.add('u9999')(重复添加自动忽略) - 移除:
blackSet.delete('u1001') - 批量更新:从新配置拉取后,用
Array.from(newList).forEach(id => blackSet.add(id)) - 定期清理过期项,或高并发读场景下用新 Set 替换旧引用,避免写竞争


















