JavaScript’s bind() Method

Something interesting about JavaScript is the way it treats functions. In JavaScript functions are first-class data and they can be passed around the same way as primitive data, like strings or arrays. Functions can be a parameter of another function, be stored in an array or be accessible from an object key. But when passing functions around their context can sometimes get lost. This is where the bind() method comes in.

The bind() method, at it’s simplest, has this format:

let boundFunc = func.bind(thisArg)

The thisArg parameter is the value to be used as the this parameter in the function func when the function is called. Another way to say this is that, when we invoke boundFunc we want to use func with the context of thisArg.

Now for an example, lets say you have a friend object:

let friend = {
name: "John",
greetFriend: function(greeting = "Hello") {
console.log(`${greeting}, ${this.name}`)
}
}
friend.greetFriend()
=> Hello, John

If you invoke the greetFriend function immediately, it works as we expect, logging with the greeting we input and the name of the friend object. But if we wanted to save the function in a new variable it wouldn’t work the same way:

let greetJohn = friend.greetFriend
greetJohn("Good morning")
=> Good morning, undefined

In this case, because we are not calling the function in relation to the friend object. Without the context of friend, the this in the greetJohn method is trying to find a variable called name in it’s own context, in this case the global scope. This is where bind() comes in. We pass as an argument to bind the context we want it to use this on. Like so:

let greetJohn = friend.greetFriend.bind(friend)
greetJohn("Good evening")
=> Good evening, John

We can also use this to bind the function to a different context than the one it came from:

let newFriend = {
name: "Jenny"
}
let greetJenny = friend.greetFriend.bind(newFriend)
greetJenny("Good afternoon")
=> Good afternoon, Jenny

One of the most important ways in which bind is useful is when you are passing a callback function to another function. So if, for example, we wanted to call to call the greetFriend method to log after two seconds we would think we could use the setTimeout function likes so:

setTimeout(friend.greetFriend, 2000)

But unfortunately, a callback doesn’t keep the context it came from. The above line equates to:

let f = friend.greetFriend
setTimeout(f, 2000)
=> Hello, undefined

One way to get around this is to use a wrapper function:

setTimeout(() => friend.greetFriend(), 2000)
=> Hello, John

But there is one possible flaw that could occur in this case. If within the two seconds before the method fires off, the greetFriend key in friend is changed, the setTimeout method will call the new method. If you use bind, setTimeout will use the pre-bound value, so this way is safer:

setTimeout(friend.greetFriend.bind(friend, "Hey there"), 2000)
=> Hey there, John

As you can see above, the bind method can also take more than just the thisArg parameter. It can also take optional arguments to plug into the function you are binding to thisArg. So another way we could use bind on the greetFriend method is like so:

let hiJohn = friend.greetFriend.bind(friend, "Hi")
hiJohn()
=> "Hi, John"

Another way you can use the optional arguments of bind is to use it on a function that doesn’t need context, for example:

function multiply(num1, num2) {
return num1 * num2
}
let double = multiply.bind(null, 2)
double(5)
=> 10

In this case, the call to bind creates a new function double that makes calls to multiply. Because we don’t need any context for the multiply function since it doesn’t use this, we pass null in as the first parameter of bind. Because we fixed 2 as the first argument, double will only take one argument and pass it to multiply in the num2 place.

Ultimately, bind() is a good method to be familiar with in JavaScript. Given the fact that JavaScript uses functions so often and in so many ways, there are many possibilities for a function’s context to get lost. If you know how to use bind() correctly you can always make sure that functions are being used in the context you intend them to be.

Software Engineer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store