Neues Node.js-Buch
Alle Artikel

Create a function for inspecting function calls

Problem

  • You want to create a generic function for inspecting function calls, so that each time the inspected function is called its name and its arguments are printed to the console.

    function createPerson(firstName, lastName) {
      return {
        firstName: firstName,
        lastName: lastName
      }
    }
    const loggingCreatePerson = inspect(createPerson);
    loggingCreatePerson('John', 'Doe');

Ingredients

  • rest parameters
  • the apply() method
  • arrow functions

Directions

  1. Create a function inspect() that accepts a function (we call this one inspected function) and returns another function. Note: the returned function will be no arrow function but a “normal” function, because then we have access to the execution context (via the this keyword).

    const inspect = fn => function (...args) {};
  2. Inside the returned function call the inspected function using the apply() method and pass the execution context and the arguments.

    const inspect = fn => function (...args) {
      return fn.apply(this, args);
    };
  3. Now before the call of the inspected function add a console output printing the name (fn.name) and the arguments (args) of the inspected function.

    const inspect = fn => function (...args) {
      console.log(fn.name + ' called with args: ' + args.join(', '));
      return fn.apply(this, args);
    };
  4. Voilá, now we have a function to inspect other functions. For example this code here …

    const inspect = fn => function (...args) {
      console.log(fn.name + ' called with args: ' + args.join(', '));
      return fn.apply(this, args);
    };
    
    function createPerson(firstName, lastName) {
      return {
        firstName: firstName,
        lastName: lastName
      }
    }
    
    const loggingCreatePerson = inspect(createPerson)
    loggingCreatePerson('John', 'Doe');

    … generates this output:

    createPerson called with args: John, Doe

Notes

  • In tomorrow’s recipe we will see how to improve the inspect() function by using a more generic approach.
  • If you don’t need access to the execution context, you can also use an arrow function for the returned function:

    const inspect = fn => (...args) => {
      console.log(fn.name + ' called with args: ' + args.join(', '));
      return fn.apply(this, args);
    };

Alternative recipes

  • Use the inspect() function of the Command Line API, available for example in Chrome, Safari and Firefox.