The first time I used .bind() I was tripped up by the fact that the optional arguments passed to the bound function are prepended. This got me when I was trying to hand things off to anonymous event handling functions, sort of like this:
$('#example').on('change', function(arg1, arg2, evt) {
console.log(evt, arg1, arg2);
}.bind(null, arg1, arg2));
The MDN for .bind() mentions the prepending several times but never elaborates, so I'm curious as to why - why do I have to put arg1
and arg2
before the evt
in the function arguments? Wouldn't appending be easier to understand and slightly more performant?
If the additional bound parameters were appended to the call time arguments, the behaviour would be like this:
function foo(bar, baz) {}
const b = foo.bind(null, 42);
b(); // bar = 42
b('c'); // bar = 'c', baz = 42
b('c', 'd'); // bar = 'c', baz = 'd'
Meaning, it is unpredictable where your bound arguments will end up, which is arguably insane.
Prepending also makes more sense if you think of bind
as partial application or currying: very loosely functionally speaking, foo.bind(null, 42)
returns a partially applied function,
it turns a -> b -> c
(a function which takes two values and returns a third)
into b -> c
(a function which takes only one more value and returns another).