Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

JavaScript bind() for Cleaner Code

DZone's Guide to

JavaScript bind() for Cleaner Code

Dave Bush shows examples of using JavaScript bind() for callbacks, event handlers, and currying.

· Web Dev Zone
Free Resource

Learn how to build modern digital experience apps with Crafter CMS. Download this eBook now. Brought to you in partnership with Crafter Software

Several weeks ago, I wrote about how closures impact calling asynchronous functions in a loop and several ways of dealing with that problem.

In my recent coding, I’ve discovered an even more simple way of dealing with this problem. In the process, it removes the anonymous function and eliminates the linting error, ‘Don’t make functions within a loop’

You see, I’ve been experimenting with JavaScript bind(). And as it turns out, we can use bind in multiple situations, including dealing with the closure issue I mentioned a couple of weeks ago.

What is bind()?

The bind function is a recent addition to the JavaScript spec, so this will only work on recent browsers. You can check the compatibility table (for all things JavaScript) to see which browsers implement bind() as well as other JavaScript features. I looked over the list and there aren’t any browsers that don’t support bind() that I care to support, so I’m good. Your mileage may vary.

Image title

What bind does is it automatically wraps your function in its own closure so that we can bind the context (the this keyword) and a list of parameters to the original function.

What you end up with is another function pointer.

function add(a,b){
    return a + b;
}

var newFoo = foo.bind(this,3,4);

console.log(newFoo());

Notice that we not only bound this to the foo() function, but we also bound the two parameters. So, when we call newFoo() the return value will be 7.

But what happens if we change the parameters before calling newFoo?

Changing Bind Parameters

If we bind parameters to foo() using variables and then change the variables prior to calling newFoo(), what do you expect the value to be?

function add(a,b){
    return a + b;
}
var a = 3;
var b = 4;
var newFoo = foo.bind(this,a, b);
a = 6;
b = 7;
console.log(newFoo());

The return value is still going to be 7 because bind() binds the value of the parameters, not the actual variables.

This is good news, and like I said, we can use this to great advantage in our code. But where I think it will display the most usefulness to me is in my call backs

Bind and Callbacks

You should remember from that article that one of our solutions to dealing with callbacks in loops was to create an anonymous function around the function we wanted to call.

for(var i = 0;i < 10;i++){
    (function(ii){
        setTimeout(function(){
            console.log(ii);
        },1000);
    })(i);
}

But we can greatly simplify this code by using bind instead.

function consoleLog(i){
  console.log(i);
}

for(var i = 0;i < 10;i++){
    setTimeout(consoleLog.bind(this,i),1000);
}

We can do this because each call to bind gives us a new function pointer and the original function remains unchanged.

Meanwhile, we also remove the linting error ‘Don’t make functions within a loop’ because we aren’t creating the function in a loop, we are just pointing to a function that was created outside of the loop.

Bind for Event Handlers

Another place where bind() will clean up your code is with event handlers. Everyone knows, or should know, that when an event handler is called, the context it is called on is the thing that generated the event and not the object that the event handler was created in. By using bind, you can be sure that the function is being called on the correct context.

function ClassName(){
   this.eventHandler = (function(){
   }).bind(this);
}

Not that you would write your code exactly like that, but that is just to get the point across.

Currying

What?!

OK.  I’ll be the first to admit that my functional programming knowledge is limited. But the best definition of Currying I can give you is that it allows you to pass parameters to function in multiple steps.

Using binding, we achieve Currying by writing code that looks something like this:

function add(a,b,c) {
  return a+b+c;
}

var addAgain = add.bind(this, 1, 2);
var result = addAgain(3); 


Crafter is a modern CMS platform for building modern websites and content-rich digital experiences. Download this eBook now. Brought to you in partnership with Crafter Software.

Topics:
closures ,javascript ,binding

Published at DZone with permission of Dave Bush, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}