If you know any object orientated language you will be very familiar with the “this” keyword. In these languages “this” refers to the current instance of the class. While this is true in JS, you might have also seen it being used inside functions. The value of this is also called context in JS.
The function context depends on how the function is being called. Also, arrow functions don’t have their own scope, the scope of it’s containing element is passed to it.
Javascript also allows you to change the context of the function using call(), apply(), bind() methods. These methods are the properties that exist on a function object.
The call() method
Using it you can pass context and arguments to a function.
Syntax
functionName.call(contextObject, funtcion args)
Lets us say you have the following functions
function multiplyByN(n) {
console.log(this.multiplier * n)
}
If you run this you will get NaN as the output since this does not have a context, making multiplier to be undefined.
Now if you want to give the function context using call you would do the following
multiplyByN.call(context, n)
so if you want to multiply 3 by 2
multiplyByN.call({ multiplier: 2 }, 3)
// Output: 6
The apply() method
The apply method works in a similar way but here the arguments are passed as an array.
multiplyByN.apply({ multiplier: 2 }, [3])
// Output: 6
The bind() method
Bind returns you a new method with the value of the context bound to it. Here is the syntax
boundFunction = functuinName.bind(context)
So the above example will become
multiplyBy2 = multiplyByN.bind({ multiplier: 2 })
multiplyBy2(3)
// Output: 6
Out of these three, bind() is very interesting since it returns a new function with the context we specified. This allows you to pass this new function to array methods, callbacks. This way you can have reusable function blocks.
Let’s take a look at a detailed example. Let’s calculate the return amount you will receive on your 1year savings. Now the purpose of this example is to demonstrate the use of bind() method, the calcReturns() function is very basic, you can change it to whatever you like.
let savings = [2000, 3000]
let calcReturns = function(ammount) {
return ammount + ammount * (this.interest / 100)
}
let calWith3percent = calcReturns.bind({ interest: 3 })
savings.map(calWith3percent)
// Output: [ 2060, 3090 ]
This would have not been possible if we had interest as an argument, as the callback of the array function has its own arguments
or if you want to check for different interest rates than
let interests = [3, 4, 7]
interests.forEach(interest => {
let calculate = calcReturns.bind({ interest: interest })
console.log(savings.map(calculate))
})
// Output: [ 2060, 3090 ] [ 2080, 3120 ] [ 2140, 3210 ]
With some proper logic in the calculate returns function you can have a pretty decent investment calculator.
Why would you use context you can pass parameters to the function?
Yes, you can just use arguments most of the times, but as you can see from the examples above at times using context will allow you to write very reusable code. You should check this StackOverflow post to get much more clarity on it.
That’s it for this post, you can read more about using bind() in this post which I had written a long while back.
If you like this post do share it :).