How to write Wrapper Functions? (aka Decorators)

Wrapping a function, also known Decorating, is parallel to inheriting from an object in the OOP world. It is a way of taking a prototype idea and extend it in a way that encourages code reuse. Moreover, it is a powerful creative tool that open doors to new ways of coding and thinking.

Say we developed a Server that logs many messages like

But it is only after we coded that we realized we forgot to log the actual time of the message. First thing that comes to mind is that the code needs to get refactored, and any appearance of console.log should be replaced with some other function that logs the time as well. This is probably the right thing to do by the way, but for the sake of curiosity wouldn’t it be nice if we could just alter console.log?

Altering console.log

Meet wrapper:

Wrapper is a function that accepts a function as a parameter and returns a function when its done. This makes it a Higher-Order Function, which is the title any function that gets or returns a function earns. The way to use wrapper in our Server is:

console.log = wrapper(console.log);

What just happened here? Lets begin from the right side of the expression, we just sent console.log as a parameter to some wrapper. Wrapper received the function, and in return, it gave back a new function. One that first prints the date, and then invokes the parameter function. The returned function eventually is set back to be console.log itself.

Note the use of console.info in the wrapper. If we used console.log to log the date, it wouldn’t work because by the time it invokes console.log is referring the wrapper, but if the wrapper is within in itself.. it means.. – – – > INFINITY !

Note that the parameter func is accessible inside the new function that is being created, and also available in the time of invoking the inner function (which turns to be console.log). This is due to Closures. In a sentence, any function, at the moment of creation, takes a snapshot of its scope which will remain available at the moment of running. This is called Closure since the scope lives just because it has a reference which is the very function that this scope actually belonged to in first place.

What a closure 🙂

Read that sentence again.

This concept also gives the opportunity for this freak to actually work:

If you are wondering how to use it, this is the way:

But you can also go straight forward:

Last Note
Wrapping a function doesn’t necessarily have to do with mutating existing functions. We could also use wrapping as a function inheritance technique.

This might actually be a more common way, but I just wanted to show off.

For more info see Decorators.

Leave a Reply

Your email address will not be published. Required fields are marked *