当前位置:首页 > JavaScript

js实现aop

2026-04-06 04:52:47JavaScript

在 JavaScript 中实现 AOP(面向切面编程)

AOP 是一种编程范式,允许在不修改原有代码的情况下,通过“切面”动态插入横切关注点(如日志、性能监控等)。以下是几种常见的实现方式:

通过高阶函数实现

利用 JavaScript 的函数特性,通过高阶函数包装目标函数:

function wrap(targetFunc, beforeFunc, afterFunc) {
  return function() {
    beforeFunc.apply(this, arguments);
    const result = targetFunc.apply(this, arguments);
    afterFunc.apply(this, arguments);
    return result;
  };
}

// 示例
const originalFunc = () => console.log("核心逻辑");
const loggedFunc = wrap(
  originalFunc,
  () => console.log("调用前日志"),
  () => console.log("调用后日志")
);
loggedFunc();

使用原型链扩展

通过修改 Function.prototype 实现链式调用:

Function.prototype.before = function(fn) {
  const self = this;
  return function() {
    fn.apply(this, arguments);
    return self.apply(this, arguments);
  };
};

Function.prototype.after = function(fn) {
  const self = this;
  return function() {
    const result = self.apply(this, arguments);
    fn.apply(this, arguments);
    return result;
  };
};

// 示例
const func = () => console.log("核心逻辑");
func.before(() => console.log("前置逻辑"))()
     .after(() => console.log("后置逻辑"));

基于 ES6 Proxy 实现

利用 Proxy 对象拦截目标对象的操作:

const createAopProxy = (target, advice) => {
  return new Proxy(target, {
    get(target, propKey) {
      const origMethod = target[propKey];
      if (typeof origMethod === 'function') {
        return function(...args) {
          advice.before && advice.before(...args);
          const result = origMethod.apply(this, args);
          advice.after && advice.after(result);
          return result;
        };
      }
      return origMethod;
    }
  });
};

// 示例
const obj = { greet: name => `Hello, ${name}` };
const proxied = createAopProxy(obj, {
  before: name => console.log(`调用参数: ${name}`),
  after: res => console.log(`返回结果: ${res}`)
});
proxied.greet("World");

使用装饰器(ES7+)

在支持装饰器的环境中(如 Babel 或 TypeScript),可直接使用语法糖:

js实现aop

function log(target, name, descriptor) {
  const original = descriptor.value;
  descriptor.value = function(...args) {
    console.log(`调用 ${name} 参数:`, args);
    const result = original.apply(this, args);
    console.log(`调用 ${name} 结果:`, result);
    return result;
  };
  return descriptor;
}

class Example {
  @log
  greet(name) { return `Hello, ${name}`; }
}

new Example().greet("AOP");

注意事项

  1. 性能影响:代理或装饰器可能引入额外开销,高频调用场景需谨慎。
  2. this 绑定:确保切面函数中的 this 上下文正确。
  3. 错误处理:可在切面中加入 try/catch 实现统一错误处理。

以上方法可根据具体需求选择,高阶函数和原型链适合简单场景,Proxy 和装饰器更适合复杂系统。

标签: jsaop
分享给朋友:

相关文章

js 实现vue模板

js 实现vue模板

实现 Vue 模板的 JavaScript 方法 通过原生 JavaScript 可以实现类似 Vue 的模板渲染功能,主要包括数据绑定、指令处理和模板解析。以下是核心实现思路: 数据绑定与…

js实现动画

js实现动画

使用 CSS 动画与 JavaScript 控制 通过 JavaScript 动态添加或移除 CSS 类来触发动画。CSS 定义关键帧(@keyframes),JavaScript 通过 classL…

js实现变形

js实现变形

使用 CSS 和 JavaScript 实现元素变形 在 JavaScript 中实现变形效果通常结合 CSS 的 transform 属性,通过动态修改该属性实现元素的旋转、缩放、倾斜或平移。 基…

js实现求导

js实现求导

实现数值求导的方法 在JavaScript中实现求导通常采用数值方法,因为JavaScript不是符号计算语言。以下是常见的数值微分方法: 中心差分法 中心差分法提供较高精度的导数近似:…

js实现目录

js实现目录

实现目录的基本思路 在JavaScript中实现目录功能通常涉及以下几个核心步骤:解析文档中的标题元素(如h1-h6),动态生成目录结构,并添加交互逻辑(如点击跳转)。以下是具体实现方法: 解析标题…

vue实现js休眠

vue实现js休眠

实现 JavaScript 休眠的方法 在 Vue 中实现 JavaScript 休眠(延迟执行)可以通过以下方式实现。由于 JavaScript 本身没有内置的 sleep 函数,通常使用 Prom…