2

我正在尝试为我的类构建一个 AOP 记录器......我遇到了一个问题,当我反射回目标函数时,该函数无法访问this

所以我的 AOP 有点像这样

AOP.js

class AOP {
  constructor() {

  }
  static ClassHandler(obj) {
    const InstanceHandler = {
      get(target, prop, receiver) {
        console.log(target.constructor.name);
        const origMethod = target[prop];
        return function (...args) {
          // let result = Reflect.apply(origMethod, this, args)
          let result = Reflect.get(target, prop, receiver)
          result = Reflect.apply(result, this, args);
          console.log(prop + JSON.stringify(args)
              + ' -> ' + JSON.stringify(result));
          return result;
        };
      },
      apply(target, thisArg, argumentsList) {
        console.log('actually applied');
      }
    }

    const handler = {
      construct(target, args) {
        console.log(`${target.name} instantiated`);
        console.log(args);
        const instance = Reflect.construct(...arguments);
        return new Proxy(instance, InstanceHandler);
      }
    }

    return new Proxy(obj, handler);
  }
}

module.exports = AOP;

单身人士

其他类.js

class OtherClass {
  constructor() {
    this._blah = 'this is a shoutout';
  }

  shoutOut() {
    console.log(this._blah);
  }
}

module.exports = new OtherClass();

和一个需要单例的类

计算器DI.js

class Calculator {
  constructor(otherClass) {
    this.otherClass = otherClass;
  }

  add(a, b) {
    this.otherClass.shoutOut();
    return a+b;
  }

  minus(a, b) {
    return a-b;
  }
}

module.exports = Calculator;

像这样把它们放在一起:

const AOP = require('./src/aspects/AOP');
const Calculator = AOP.ClassHandler(require('./src/CalculatorDI'));
const otherClass = require('./src/OtherClass');
const calculator = new Calculator(otherClass);

calculator.add(1,1);

运行此程序时,我收到错误:

TypeError:this.otherClass.shoutOut 不是函数

4

1 回答 1

1

您的问题是您的代理总是为访问的任何属性返回一个函数,包括this.otherClass. 您将需要使用

const instanceHandler = {
  get(target, prop, receiver) {
    console.log(target.constructor.name);
    const orig = Reflect.get(target, prop, receiver);
    if (typeof orig == "function") {
//  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      return function (...args) {
        const result = orig.apply(this, args);
        console.log(prop + JSON.stringify(args) + ' -> ' + JSON.stringify(result));
        return result;
      };
    } else {
      return orig;
    }
  }
};

另请注意,您不需要在apply中设置陷阱instanceHandler,因为您的实例都不是函数。

于 2018-07-07T08:12:33.743 回答