javascript可通过闭包封装路由状态与拦截逻辑,每个路由实例独立维护匹配条件、前置钩子和跳转行为,实现状态私有、多实例共存及异步钩子串行执行。

JavaScript 可以通过闭包封装路由状态和拦截逻辑,让每个路由规则独立维护自己的匹配条件、前置钩子和跳转行为,同时避免全局变量污染。
用闭包保存路由配置与钩子函数
闭包的核心是让内部函数持续访问外部函数作用域中的变量。我们可以把路由表、当前路径、以及注册的拦截器(如登录校验、权限检查)都定义在工厂函数内部,只暴露注册和触发方法:
- 外部无法直接修改路由表或当前路径,保证状态私有
- 每次调用工厂函数生成一个独立的路由实例,支持多路由系统共存
- 钩子函数(如
beforeEach)可被多次注册,按顺序执行并支持中断跳转
实现一个基础的拦截器工厂
下面是一个轻量、可复用的闭包式路由拦截器示例:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
function createRouter() {
let currentPath = window.location.pathname;
const routes = new Map();
const beforeEachHooks = [];
// 注册前置钩子
function beforeEach(fn) {
beforeEachHooks.push(fn);
}
// 注册路由路径与处理函数
function add(path, handler) {
routes.set(path, handler);
}
// 手动触发跳转(含拦截)
async function navigate(toPath) {
// 执行所有前置钩子,任一返回 false 则中止
for (const hook of beforeEachHooks) {
const result = await hook(toPath, currentPath);
if (result === false) return;
}
const handler = routes.get(toPath);
if (handler) {
currentPath = toPath;
handler();
}
}
// 监听浏览器前进/后退(可选)
window.addEventListener('popstate', () => {
const newPath = window.location.pathname;
navigate(newPath).catch(() => {});
});
return { add, beforeEach, navigate };
}
// 使用示例
const router = createRouter();
router.beforeEach((to, from) => {
if (to === '/admin' && !localStorage.getItem('token')) {
alert('请先登录');
return false; // 阻止跳转
}
});
router.add('/', () => console.log('首页'));
router.add('/admin', () => console.log('管理页'));
// 模拟跳转
router.navigate('/admin');
关键细节说明
这个闭包结构的关键在于:
-
状态隔离:每个
createRouter()调用都创建全新作用域,互不影响 -
钩子可控:支持异步钩子(如检查登录态需发请求),用
await串行执行 -
路径匹配可扩展:当前用精确匹配,后续可将
routes改为数组 + 正则匹配逻辑,不破坏闭包结构 - 不依赖框架:纯 JS 实现,可嵌入任何项目,包括静态页面或微前端子应用
进阶提示:支持参数解析与命名路由
若需类似 /user/:id 的动态路由,可在 navigate 中增加路径解析逻辑,并把参数透传给 handler:
- 用正则或
URLPattern(现代浏览器)提取参数 - handler 接收参数对象,如
handler({ id: '123' }) - 这些增强逻辑仍可封装在闭包内,不暴露内部解析器
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










