
Partial Application in JavaScript using bind() - ch0wn
http://passy.svbtle.com/partial-application-in-javascript-using-bind
======
timothya
I've used bind to do partial function application for quite a while, and it
really is a convenient pattern to use. It does have the downside that it's a
bit harder to quickly understand what's going on, though, since the arguments
being passed into a function can come from different places.

My common use case is when I'm setting up event handlers and I want the event
handler to know about a companion object I have to the element in the DOM. For
example:

    
    
        MyObject.prototype.buildDom_ = function() {
          for (var i = 0; i < buttons.length; i++) {
            var button = new MyButton(...);
            this.myButtons_.push(button);
            var element = document.createElement('div');
            element.addEventListener('click', this.handleClick_.bind(this, button));
            this.rootElement_.appendChild(element);
          }
        };
    
        MyObject.prototype.handleClick_ = function(button, clickEvent) {
          // I have access to the MyButton instance passed in.
        };
    

In this case, I use the partial application to pass in the MyButton instance
so that when I'm in the handler for a button click, I have access to the
original JavaScript object that was created when the event handler was set up.

------
mike-cardwell
Note: Function.prototype.bind doesn't exist in IE8 and below. There is a
Polyfill at [https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Refe...](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) which adds it
when it is missing.

~~~
jbaudanza
Also the es5-shim library is quite nice, and includes a bind polyfill.
[https://github.com/es-shims/es5-shim](https://github.com/es-shims/es5-shim)

------
geuis
It's not entirely clear to me how bind is different than apply.

~~~
timothya
The big difference is that unlike `apply` (and `call`), `bind` does not call
the function, it just gives you a new function that you have to call later (or
use as an event handler).

`bind` returns a new function, which has it's context `this` set to whatever
you pass in, along with arguments partially applied.

`apply` calls the function, using the context object you provide and the
arguments provided in an array. (`apply` also has a sister function `call`,
which also calls the function with the context object you provide and the
arguments you provide individually).

~~~
geuis
Ahh that is a subtle but useful distinction. Didn't pick up on that in mdn.
Thanks for the tip.

------
natecavanaugh
Two useful things YUI provides around this (and I'm sure other libraries have
similar), are:

1\. Y.rbind, which does the same thing as bind, but appends the arguments (to
me, this is more useful, as often, I'm binding a single function thats defined
somewhere that expects at least the event obj as the first arg, but may be
able to handle optional arguments that I could bind to an instance of that fn)

2\. The ability to create a bound function using only the name of the function
and the object it exists on. Using something like Y.bind('myFn', obj);, the
function that will be executed will be looked up at runtime rather than at the
time the bound fn is created. This is extremely useful for cases where you may
be using AOP or monkey patching to displace a function before it's executed.
It also allows you to bind a function before it exists. Passing in a reference
to the function at bind time protects against cases like that, but I find it
far more useful than just binding the reference.

------
jasonlotito
A bit more comprehensive article can be found here:

[http://coding.smashingmagazine.com/2014/01/23/understanding-...](http://coding.smashingmagazine.com/2014/01/23/understanding-
javascript-function-prototype-bind/)

------
mcgwiz
For partial argument binding, I find myself using an implementation that
doesn't close 'this' much more often. E.g.

    
    
      Function.prototype.partial = function () {
        var 
          fn = this,
          args = Array.prototype.slice.call(arguments)
        ;
        return function() { 
          var newArgs = Array.prototype.slice.call(arguments);
          return fn.apply(this,args.concat(newArgs));
        }
      }

------
taylodl
Bind can also be used to obtain a reference to a function expression in
javascript. I exploited that ability in creating an implementation of
trampoline in javascript: [http://taylodl.wordpress.com/2013/06/07/functional-
javascrip...](http://taylodl.wordpress.com/2013/06/07/functional-javascript-
tail-call-optimization-and-trampolines/)

------
pencilcode
I've heard bind is slow. Is this still true?

~~~
vectorjohn
Slow in what way? If you think about what it's doing, it can only be so slow.
Assuming the browser's engine doesn't do any sort of optimization (bind is a
native method, so it might), it is simply creating an anonymous function that
calls the original. So it's an extra function call:

var boundFn = function(){ return originalFunction.apply( this, [boundArg1,
boundArg2].concat( arguments ) ); }

or something like that.

~~~
kevingadd
It's significantly slower than doing it by hand because of how .bind() is
implemented in v8 and spidermonkey. It messes with the type information the
engines use to optimize and it often sends you through C++ to do the function
call.

~~~
cjfont
So is it .bind() itself that is slow, or the function that it returns?
Assuming the bind operation itself is done during initialization, its slowness
is pretty irrelevant.

~~~
kevingadd
Bind itself is slower than doing it by hand with a closure, and the return
value is an order of magnitude slower than the hand-written closure _and_
pollutes type information for your entire application, making all your code
slower.

~~~
rtpg
why not use a "JS-native"implemtation then? Are there some issues with the
spec that need to be respected?

~~~
kevingadd
I'm not aware of any good reason to use Function.bind. Presumably at some
point in the future VMs could optimize it such that it would be faster than a
native JS polyfill, but right now the polyfill is superior. If you just want
to slam out some JS one-liners, though, you obviously want to use built-in
functions where possible.

------
cocoflunchy
My issue is how to remove the event listener once you've done

    
    
        document.addEventListener('click', handleEvent.bind(this));
    

Doing

    
    
        document.removeEventListener('click', handleEvent);
    

doesn't work, so how can you get rid of it?

~~~
timothya
You could do:

    
    
        var boundEvent = handleEvent.bind(this);
        document.addEventListener('click', boundEvent);
    

and later:

    
    
        document.removeEventListener('click', boundEvent);
    

This situation is a bit messier, though, because you have to keep track of
both `handleEvent` and `boundEvent`.

~~~
cocoflunchy
Now it seems obvious... thank you ;)

------
ghostdiver
This "pattern" is wrong, it makes debugging much harder. In some cases less
code means more pain and this is such case.

~~~
Vekz
This is poor communication. Saying its 'wrong' and makes it 'harder' are your
personal generalizations. Thats an empty statement. How does it do either of
those?

This pattern encourages naming of anonymous functions that are used in
callbacks. Which creates simpler stack traces. The new piece here about
passing additional params to bind is also helpful, in that it will allow you
to carry params across a callback stack. For me this will make carrying an
express apps request and response objects across a callback chain much easier.

~~~
ghostdiver
It forces programmer to make few more steps during debugging process, using
conditional breakpoints in particular.

not a big deal to put conditional breakpoint in handleStreamEvent whereever it
is, but in long run it just a waste of time.

    
    
      this.setup = function () {
        this.on('tweet', this.handleStreamEvent.bind(this, 'tweet'));
        this.on('retweet', this.handleStreamEvent.bind(this, 'retweet'));
      };
    

This pattern will be obsolote as soon as arrow function gets implemented by
all major browsers:

    
    
      this.setup = function () {
        this.on('tweet', () => this.handleStreamEvent('tweet'));
        this.on('retweet', () => this.handleStreamEvent('retweet'));
      };

~~~
ch0wn
Those are not equivalent. You still have to pass on the parameters:

    
    
        this.setup = function () {
          this.on('tweet', (e, data) => this.handleStreamEvent('tweet', e, data));
          this.on('retweet', (e, data) => this.handleStreamEvent('retweet', e, data));
        };

~~~
ianstormtaylor
Good catch. Once they are added though, it feels a lot more readable than the
"bind" alternative.

------
lennel
the use of bind with event listeners will lead to memory leaks since you have
no way of removing the event listener, given that you don't have access to the
function bind returns (at least in the code examples the writer created).

------
epx
I just prefer the explicit self, like Python's

------
benihana
This is also possible with jQuery's proxy function if you can't target only
modern browsers.

[http://api.jquery.com/jquery.proxy/](http://api.jquery.com/jquery.proxy/)

