
本文介绍如何基于两个对象数组(系统全部模块和用户可访问模块),遍历每个模块的动作列表,生成标准化的权限标记结构:存在则为 1,不存在则为 0。
本文介绍如何基于两个对象数组(系统全部模块和用户可访问模块),生成标准化的权限标记结构:存在则为 `1`,不存在则为 `0`。
在权限管理类系统中,常需将完整的功能模块定义(如 modules)与当前用户的实际操作权限(如 user_modules)进行比对,并以键值对形式直观呈现每项动作是否被授权。注意:user_modules 仅包含部分模块及其子集动作,而 modules 是全量定义;目标不是合并对象,而是“按 modules 结构补全、按 user_modules 判定”。
以下是一个健壮、可读性强的实现方案:
const modules = {
"member": {
"actions": ["create", "edit"]
},
"subscription": {
"actions": ["create", "edit", "move_out", "renew", "void"]
}
};
const user_modules = {
"subscription": {
"actions": ["create", "edit"]
}
};
// 核心转换逻辑
const result = {
modules: Object.fromEntries(
Object.entries(modules).map(([moduleName, moduleDef]) => {
const userModule = user_modules[moduleName] || { actions: [] };
const userActions = new Set(userModule.actions); // 提升查找效率
const actionMap = Object.fromEntries(
moduleDef.actions.map(action => [
action,
userActions.has(action) ? 1 : 0
])
);
return [moduleName, { ...moduleDef, actions: actionMap }];
})
)
};
console.log(JSON.stringify(result, null, 2));输出示例:
{
"modules": {
"member": {
"actions": {
"create": 0,
"edit": 0
}
},
"subscription": {
"actions": {
"create": 1,
"edit": 1,
"move_out": 0,
"renew": 0,
"void": 0
}
}
}
}✅ 关键设计说明:
- 使用
Object.entries()+Object.fromEntries()实现声明式对象映射,语义清晰; - 对
user_modules[moduleName]?.actions做安全访问,并默认为空数组,避免undefined报错; - 用
Set存储用户动作,使has()查找时间复杂度为 O(1),大幅提升大数据量下的性能; - 严格保持原始
modules的模块结构与顺序,仅重写actions字段为对象格式(非数组),符合需求中"create": 1的键值对形式。
⚠️ 注意事项:
- 此方案假设
modules和user_modules的键(如"member"、"subscription")均为字符串且一一对应;若存在模块名不一致情况,需额外做对齐处理(如取并集或过滤); - 若未来需支持嵌套权限(如
actions.create.sub_actions),建议封装为递归函数; - 生产环境建议增加类型校验(如使用 TypeScript 或运行时 schema 验证),防止字段缺失导致静默错误。
该方法简洁、可扩展,适用于 RBAC 权限渲染、前端菜单动态禁用、API 权限预检等典型场景。

















