【问题标题】:Run a function every time any function in class is called using JS每次使用 JS 调用类中的任何函数时运行一个函数
【发布时间】:2023-03-27 15:49:01
【问题描述】:

我有这样的简单课程:

module.exports = class MyClass {

    function middleware() {
        console.log('call me before')
    }

    function a() {

    }
    function b() {

    }

    function c() {

    }
}

所以想法是,当有人调用函数 a、b、c 时,我想在执行 a、b、c 之前调用中间件。我该怎么做?

所以,我可以将 middleware() 放到每个函数中,但我想要一些动态的方式来做到这一点。

【问题讨论】:

  • 如果你调用函数a(),你什么也做不了,它只会执行a。
  • 我相信有办法。
  • 也许你在这个答案stackoverflow.com/questions/5033836/… 中找到了一些东西
  • 如果您愿意使用 ESNext 的反向移植功能,您可以随时使用decorators。 Babel 有一个this 的插件。
  • 看看AOP(面向方面​​编程),它可以解决这样的问题。 javascript 中的一个实现:blog.bitsrc.io/…

标签: javascript


【解决方案1】:

您可以使用Proxy 来捕获实例上的每个属性访问,并包装函数。

class MyClass {
  constructor() {
    const handler = {
      get: function (obj, prop) {
        return typeof obj[prop] !== "function"
          ? obj[prop]
          : function (...args) {
              obj.middleware(prop);
              obj[prop].apply(obj, args);
            };
      },
    };
    return new Proxy(this, handler);
  }

  middleware(prop) {
    console.log(`Executing function ${prop}`);
  }

  a() {}

  b() {}

  c() {}
}

const obj = new MyClass();

obj.a();
obj.b();
obj.c();

【讨论】:

    【解决方案2】:

    您可以通过遍历所有自己的属性名称来重写类原型的所有方法(Object.keysfor..in 在此处不起作用,因为类方法不可枚举),然后用新方法替换原始方法调用原始方法但也调用中间件。这样类行为不会改变,但会调用中间件。

     class MyClass {
        a() { console.log("a"); }
     }
    
     function middleware() { 
        console.log("works");
     }
    
     for(const key of Object.getOwnPropertyNames(MyClass.prototype)) {
         const old = MyClass.prototype[key];
         MyClass.prototype[key] = function(...args) {
           middleware(...args);
           old.call(this, ...args);
         };
     }
    
     (new MyClass).a();

    【讨论】:

    • 完全取决于用例,这里你不能写组件特定的东西,或者不能事件绑定上下文。
    【解决方案3】:

    你可以不直接调用a,b,c函数,你可以调用中间件并在参数中传递函数,中间件最后会调用它。

    function middleware(targetFunction) {
        console.log('call me before');
        targetFunction();
    }
    

    【讨论】:

    • 当然,是的,有可能。
    • 这可能会导致问题。传递给middleware 的函数将失去它们的上下文,换句话说,其中的this 很可能是实例以外的东西。
    • 取决于你调用函数的方式/形式,你总是可以绑定它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-11
    • 1970-01-01
    相关资源
    最近更新 更多