数组角色精准匹配异常:调用hasAuthorization为何返回true?
你的console.log返回true的核心原因是hasAuthorization方法的逻辑完全偏离了需求,同时正则的使用属于冗余且易出错的操作,具体问题和修复方案如下:
核心问题
逻辑完全错误:
调用UserRole.hasAuthorization(ROLE_USER_ADMIN)时,方法内部遍历roles数组的第一个元素ROLE_ADMIN,此时UserRole.regexAdmin.test(role)返回true,代码直接return true——完全忽略了传入的ROLE_USER_ADMIN参数,也没有完成后续遍历。
另外,方法的default分支会在第一个不匹配的角色时就返回false,导致如果数组中第一个角色不匹配但后续有匹配项的场景,也会错误返回false。正则冗余且存在潜在风险:
你需要的是精确字符串匹配,用正则完全没必要。\b(单词边界)的判断逻辑是仅在单词字符(a-z/A-Z/0-9/_)与非单词字符的交界处生效,而你的角色都是下划线连接的字符串,这可能导致边界匹配不符合预期,反而增加出错概率。
修复方案
方案一:使用数组原生方法(最简洁高效)
Array.prototype.includes专门用来检查数组中是否存在指定精确值,完全符合你的需求:
export const ROLE_ADMIN = "ROLE_ADMIN"; export const ROLE_USER_ADMIN = "ROLE_USER_ADMIN"; export const ROLE_MARKETING = "ROLE_USER_ADMIN_MARKETING"; export const ROLE_TECHNICAL = "ROLE_USER_ADMIN_TECHNICAL"; // 增加默认值避免localStorage无数据时JSON.parse报错 const roles: string[] = JSON.parse(localStorage.getItem("roles") || "[]"); class UserRole { public static hasAuthorization(targetRole: string): boolean { return roles.includes(targetRole); } } export const hasAdmin = UserRole.hasAuthorization(ROLE_USER_ADMIN); console.log(hasAdmin); // 现在会返回false,符合预期
方案二:修正原循环逻辑(适合需要扩展的场景)
如果需要保留类结构和遍历逻辑,只需修正为检查每个角色是否与传入的目标角色完全相等即可:
export const ROLE_ADMIN = "ROLE_ADMIN"; export const ROLE_USER_ADMIN = "ROLE_USER_ADMIN"; export const ROLE_MARKETING = "ROLE_USER_ADMIN_MARKETING"; export const ROLE_TECHNICAL = "ROLE_USER_ADMIN_TECHNICAL"; const roles: string[] = JSON.parse(localStorage.getItem("roles") || "[]"); class UserRole { public static hasAuthorization(targetRole: string): boolean { // 遍历所有角色,找到完全匹配的立即返回true for (const role of roles) { if (role === targetRole) { return true; } } // 遍历完无匹配项才返回false return false; } } export const hasAdmin = UserRole.hasAuthorization(ROLE_USER_ADMIN); console.log(hasAdmin); // 返回false
关于switch语句的问题
你确实不该用switch来实现这个逻辑——你的switch是对每个遍历到的角色,检查是否匹配任意预定义正则,这相当于判断数组中是否存在任意一个预定义角色,而非判断是否存在你指定的目标角色,完全不符合需求。
内容的提问来源于stack exchange,提问作者Johan

