闭包是JavaScript实现AOP动态织入前后置通知的核心机制,通过函数嵌套和作用域捕获,在不修改原函数前提下挂载日志、校验等横切逻辑;前置通知在内层函数中先执行beforeFn再调用originalFunc.apply(this, arguments);后置通知通过try...catch+finally确保afterFn总能执行;around模板直接替换目标方法,兼顾轻量性与调试友好性。

闭包是 JavaScript 实现 AOP 动态织入前后置通知的核心机制。它不依赖框架或 Proxy,靠函数嵌套和作用域捕获,就能在不修改原函数的前提下,把日志、校验、监控等横切逻辑“挂”到目标函数执行的前后。
闭包如何承载前置(before)通知
前置通知需要在目标函数调用前执行,同时保留对原函数和调用上下文的访问能力。闭包天然满足这两点:外层函数接收原函数和通知逻辑,内层函数作为新入口,在执行原函数前先运行通知。
- 外层函数接收 originalFunc 和 beforeFn,返回一个新函数
- 新函数内部先调用 beforeFn(),再用 .apply(this, arguments) 正确传递上下文与参数
- 这样既没动原函数,又确保每次调用都触发前置行为
闭包如何支撑后置(after)通知
后置通知关注的是执行结果或副作用清理,比如记录耗时、释放资源、打日志。闭包让通知能“看到”原函数的返回值和可能抛出的异常。
- 新函数包裹原函数调用,用 try...catch 捕获异常,保证 after 逻辑总能执行
- 无论成功或失败,都在 finally 块中运行 afterFn(),或在 try 块末尾单独调用
- 闭包保存了 afterFn 和原始调用意图,使行为可复用、可组合
闭包解决 this 和参数传递的关键细节
直接包装函数容易丢失 this 和 arguments,这是 AOP 织入失败的常见原因。闭包配合 .apply() 或展开语法能精准还原执行环境。
立即学习“Java免费学习笔记(深入)”;
- 不能写 originalFunc() —— 这会丢失 this,变成全局调用
- 必须写 originalFunc.apply(this, arguments) 或 originalFunc(...arguments)
- 如果通知函数也需要访问 this 或参数,就把它也闭包进内层函数作用域里
一个可复用的 around 闭包模板
环绕通知是最灵活的形式,它把 before、原函数、after 封装在一个闭包里,控制权完全交由开发者掌握:
const around = (target, method, beforeFn, afterFn) => {const original = target[method];
target[method] = function(...args) {
beforeFn.call(this, ...args);
const result = original.apply(this, args);
afterFn.call(this, result, ...args);
return result;
};
};
这个模式不生成代理对象,而是直接替换方法,轻量、透明、调试友好。



















