Array.prototype.includes 适合校验用户是否拥有任一离散权限,语义清晰且简洁;但不支持通配符、层级匹配或模糊搜索,遇复杂权限逻辑需改用 some + startsWith、正则或自定义函数。

Array.prototype.includes 能直接替代一堆 if-else 或 switch 判断权限码,前提是权限码是离散、可枚举的字符串或数字,且校验逻辑是“是否拥有任一权限”——不是“必须同时拥有多个”,也不是“需按优先级匹配”。否则强行套用反而埋坑。
权限码是字符串数组时,直接用 includes 判定用户是否有某项权限
常见场景:后端返回用户权限列表 userPermissions = ['user:read', 'order:edit', 'report:view'],前端要控制某个按钮是否显示。
错误写法(冗余):
if (userPermissions.indexOf('order:edit') !== -1) { ... }
正确写法(简洁且语义清晰):
if (userPermissions.includes('order:edit')) { ... }
-
includes返回布尔值,语义比indexOf !== -1更直白 - 注意:它不支持正则或模糊匹配,
'order:edit'必须完全相等 - IE 不支持,如需兼容 IE,要么加 polyfill,要么退回
indexOf
多个权限任一满足就放行?用 some + includes 组合,别硬写链式 includes
比如按钮需要「有编辑权限」或「是管理员」才能操作,权限码分别是 'post:edit' 和 'admin:all'。
错误写法(可读性差、难扩展):
if (perms.includes('post:edit') || perms.includes('admin:all')) { ... }
推荐写法(逻辑分层,后续加权限更安全):
const requiredPerms = ['post:edit', 'admin:all'];<br>if (requiredPerms.some(p => perms.includes(p))) { ... }
- 把“所需权限集合”抽成变量,避免魔法字符串散落各处
- 不要用
includes去查一个长数组是否包含多个值——那是some的职责 - 如果权限码存在层级(如
'user:*'),includes无能为力,得换正则或自定义匹配函数
权限码带通配符或前缀时,includes 会失效,必须改用 some + startsWith 或正则
例如权限码是 'article:*',用户权限列表里有 'article:publish',此时 includes('article:*') 永远返回 false。
正确做法(按前缀匹配):
const hasArticlePerm = userPermissions.some(p => p.startsWith('article:'));
或更通用的通配符处理(简单星号):
function matchPermission(perm, pattern) {<br> if (!pattern.includes('*')) return perm === pattern;<br> const [prefix] = pattern.split('*');<br> return perm.startsWith(prefix);<br>}<br>const allowed = userPermissions.some(p => matchPermission(p, 'article:*'));
-
includes是精确匹配,不是通配符引擎 - 一旦权限设计引入通配、层级、继承,就必须跳出
includes思维,用更可控的字符串/正则逻辑 - 别在生产环境用
eval或动态构造正则来解析权限模式,容易被注入
真正容易被忽略的点:权限码大小写敏感、前后空格、冒号拼写错误——这些都会让 includes 静默失败。建议在登录后立刻对 userPermissions 做一次 map(p => p.trim()) 规范化,而不是每次校验都补 .trim()。

















