Function context in JavaScript

December 23, 2018

3 min read

Context

Photo by sydney Rae on Unsplash

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 :).