Improving Function.prototype.bind

John-David Dalton john.david.dalton at gmail.com
Sun Jan 8 21:22:01 PST 2012


Just a bit of back story on Function#bind because I think it's good to know.
Prototype's Function#bind was based on the 2004 post "Object-Oriented
Event Listening through Partial Application in JavaScript" by Daniel
Brockman:
http://web.archive.org/web/20100901172230/http://brockman.se/2004/method-references/

There was no de-facto standard of Function#bind. ExtJS, PrototypeJS,
MooTools, Dojo, and jQuery each had their own implementations.

MooTools Function#bind used to be implemented like:
  function fn() {
    console.log([].slice.call(arguments));
  }
  var f = fn.bind({}, ['a', 'b']); // notice an array of arguments
  f('c'); // ['a', 'b'] // ignored arguments passed to the bound function

Ext's implementation is completely different:
http://www.sencha.com/learn/legacy/Manual:Utilities:Function#createDelegate

Even though Dojo and jQuery implementations don't extend
Function.prototype they follow Prototype's implementation with the
exception that they also allow passing a string instead of a function
and jQuery adds a `guid` property to the bound function.
http://dojotoolkit.org/api/dojo.hitch
http://api.jquery.com/jQuery.proxy/#example-1

Prototype 1.7's Function#bind (which overwrites native bind too) isn't
as ES5 compliant as it could be because its bound function doesn't
behave correctly when called as part of a new expression.

  function Foo(a,b,c) {
    this.a = a;
    this.b = b;
    this.c = c;
  }
  var Bound = Foo.bind({}, 1, 2);
  var b = new Bound(3);
  console.log(Object.keys(b));  // [], but should be ['a', 'b', 'c']
  console.log(b.c) // undefined, but should be 3

- JDD


More information about the es-discuss mailing list