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
-
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 thethis
keyword).const inspect = fn => function (...args) {};
-
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); };
-
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); };
-
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.