最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Run a function every time any function in class is called using JS - Stack Overflow

programmeradmin9浏览0评论

I have simple class like this:

module.exports = class MyClass {

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

    function a() {

    }
    function b() {

    }

    function c() {

    }
}

So Idea is, when someone call function a, b, c I want call middleware before execute a, b, c. How can I do it?

So, I can put middleware() to each function, but I want some dynamic way how to do this.

I have simple class like this:

module.exports = class MyClass {

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

    function a() {

    }
    function b() {

    }

    function c() {

    }
}

So Idea is, when someone call function a, b, c I want call middleware before execute a, b, c. How can I do it?

So, I can put middleware() to each function, but I want some dynamic way how to do this.

Share Improve this question edited Aug 17, 2018 at 21:45 Lee Taylor 7,99416 gold badges37 silver badges53 bronze badges asked Aug 17, 2018 at 21:31 kinacexolikinacexoli 1531 silver badge6 bronze badges 5
  • if anytime you will call function a(), you cant do anything , it will only execute a. – Atul Commented Aug 17, 2018 at 21:35
  • I believe there is some way. – kinacexoli Commented Aug 17, 2018 at 21:36
  • Maybe you find something in this answer stackoverflow.com/questions/5033836/… – villu164 Commented Aug 17, 2018 at 21:38
  • If you're willing to use backported features from ESNext, you can always use decorators. Babel has a plugin for this. – Akshat Mahajan Commented Aug 17, 2018 at 21:43
  • Check out AOP (aspect-oriented programming), it can solve such problems. An implementetion in javascript: blog.bitsrc.io/… – Herbertusz Commented Dec 28, 2021 at 23:56
Add a comment  | 

3 Answers 3

Reset to default 10

You could rewrite all the methods of the classes prototype by iterating over all own property names (Object.keys or for..in would not work here as class methods are not enumerable) and then replacing the original methods by a new method that calls the original method but also calls the middleware. Through that the classes behaviour doesnt change, but the middleware gets called.

 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();

You could use Proxy in order to trap every property access on the instance, and wrap functions.

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();

what you can is instead of calling directly function a,b,c , you can call middleware and pass the function in the parameter , middleware will call it at last.

function middleware(targetFunction) {
    console.log('call me before');
    targetFunction();
}
发布评论

评论列表(0)

  1. 暂无评论