call(), the second part covered
apply(), and this time it’s all about
bind(). All three are great tools to have, but as you’ll see,
bind() works a little differently than the others.
Creating Functions with bind()
apply() invoke a function immediately,
bind() does not. Instead, it copies an existing function, but with a new
this and argument list bound to it. It’s up to you to invoke this new function when you want.
In this example, a new function is created with
'woof' essentially hard-coded as arguments (ignore
this for now, we’ll discuss it next).
Just like with
apply(), the first argument passed to
bind() allows you to control scope by specifying what
this refers to when inside the function.
bind() is useful for creating callback functions that need arguments passed in. These argument values are “locked-in”, even if something changes them before the function has a chance to execute. To demonstrate, let’s start with an example that doesn’t use
logValue() is called 3 times, but thanks to
setTimeout(), the calls don’t start happening until after the
for loop has completed. By that point, the value of
i has incremented to 3 — so that’s what gets logged. It doesn’t matter what
i was when each timeout was created, only what
i is when each timeout fires.
Let’s try again, but with
This time we used
bind() to bind
logValue() with the value of
i at the moment each timeout was created. So even though
i becomes 3 before any timeouts have fired, each call to
logValue() is still holding on to its own bound value of
i, giving us the intended result.
Binding Partial Argument Lists
You can still pass additional arguments into a function created by
bind(), even if you’ve already bound some arguments to it. The additional arguments are added to the end of the argument list. This lets you set up a function that has some arguments essentially hard-coded, then reuse that function with only the remaining arguments being variable.
bind() is newer than
apply(), but no worries. It’s supported in just about any browser you’d care about… unless you care about IE8 or below. In which case, consider using Underscore’s
bind() (documentation here) or jQuery’s
proxy() (documentation here) to do the job.
bind() is an interesting one. The concept of calling a function on a function to create a new function might sound bizarre at first, but it’s not so bad, and the utility it provides is definitely worth giving it a chance.