The debounce function is a higher order fn because it takes in a fn as an argument and returns a curried fn.
It returns a new fn that is only called after a certain wait time has ellapsed. It is useful for preventing repetitive
and redundant function calls which can have an impact on performance.
Code explanation:
the debounce func takes in the func to be run after a set time and a wait time in ms.
The first thing we do is initialize a timer variable and set it to undefined.
we then create a new anonymous fn and assign it to the debouncedFunc variable. This func takes all the supplied argment
and spreads it into an array. The line (...args) is responsible for that.
If a timer had started, we immediately clear the timer with the clearTimeout method.
after than, we create a timer with the setTimeout function whhich takes in a callback and the wait time supplied.
Line 8 is where we apply the proper this to the function as well as it's supplied argument args
We need to ensure that we invoke the callback fn passed to setTimeout with the correct this value: the value of this when the debounced fn was called.
It is important the the this is determined by the call-site of the function i.e where the function was called.
In the debounce implementation, to properly preserve the this we could either factor out the this into a separate variable or use an arrow fn
const context = this
//setTimeout also has a way of losing the this binding. the apply method helps solve that
setTimeout(() => {
func.apply(this, args)
}, wait)an alternative solution is this(pun intended):
setTimeout(() => {
func.apply(this, args)
}, wait)In the arrow fn case, the value of this is "bound to the context in which the function is created, not to the environment in which the function is called"