javascriptmethodsinterceptorcontrol-flowproxy-pattern

What are ways of intercepting function calls or changing a function's behavior?


I would like to execute some code every time some functions in an object are called and finish executing.

Object:

{
    doA() {
        // Does A
    },
    doB() {
        // Does B
    }
}

Is it possible to extend it, changing those functions so that they will do what they do and after do something else? Like it was an event listening for those functions finishing?

{
    doA() {
        // Does A
        // Do something else at end
    },
    doB() {
        // Does B
        // Do something else at end
    }
}

Maybe this would be possible using Proxy https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy

Tried with proxy:

const ob = {
    doA() {
        console.log('a');
    },
    doB() {
        console.log('b');
    }
};

const ob2 = new Proxy(ob, {
  apply: function (target, key, value) {
    console.log('c');
  },
});

ob2.doA();

Solution

  • Using Proxy we can target all get which includes functions, then we can check if what is being get is a function and if it is we create and return our own function that wraps the object function and call it.

    After the object function is called from within our wrapper function we can execute whatever we want and then return the return value of the object function.

    const ob = {
      doA(arg1, arg2) {
        console.log(arg1, arg2);
        return 1;
      },
      doB() {
        console.log('b');
      }
    };
    
    const ob2 = new Proxy(ob, {
      get: function(oTarget, sKey) {
        if (typeof oTarget[sKey] !== 'function')    return oTarget[sKey];
    
        return function(...args) {
          const ret = oTarget[sKey].apply(oTarget, args);
    
          console.log("c");
    
          return ret;
        }
      }
    });
    
    console.log(ob2.doA('aaa', 'bbb'));

    If there are improvements or other options please add a comment!