a lot of folks, myself included, are confused at first by bind.
Originally Posted by Dormilich
my big "aha" moment of understanding came by lining it up with the other two Function.prototype methods we all use and love; call() and apply().
turns out, bind() is EXACTLY like call() : it sets "this" with the first argument, and passes all other specified arguments as passed to the function you are calling it on. the only diff is that call() executes the function right there, whereas bind() stops short, returning the scoped function (the same as call would use) instead of the result.
let's throw bind() out, and examine the issue with the 1999 pieces.
you may have done something like this at some point:
you need to use "something" there for the same reason as zero (or something else) in my code.
apply's first argument is sucked into this.
if all that was passed was the array, max() would be called with the array as this, and with no arguments. apply() wants an array of arguments as arguments to turn into arguments on the applied function.
the reason this works is because Math.max() doesn't look at this, it only looks at it's arguments, one number per argument:
less obvious in my code is what's being bound.
Math.max.bind(0)([1,2,3]) //won't work
Math.max.call(0)([1,2,3]) //won't work
Math.max.call(0, [1,2,3]) // won't work
Math.max.call(0 ,1,2,3) // works
Math.max.apply(0, [1,2,3]) // works
Math.max.apply(999, [1,2,3]) // works
it's not max(), it's apply().
check this out:
yeah, that's weird, but it works because apply() doesn't care what is in front or behind it. it's a generic. i guess you can think of it as being "loose"; it doesn't care what function, this, or arguments it's hooked up with. heh.
max([1,2,3]) // ===3
the apply() generic steps this out for greater detail:
apply() wants two args: a new this and an array of other arguments.
apply=Function.prototype.apply; //the template for "all applies"
max=apply.bind(Math.max, 0); //bind apply to max
max([1,2,3]); //call apply, bound to max, on argument
bind wants 1+ arguments: this and others to pre-bake.
thus, we are essentially stacking the args for apply onto the args for max().
again, we can break it down to zoom in.
the apply() method can be (jankily) written in userland using call:
var code= "this.call(that," + args + ")" ;
"call code: "+code,
"this: "+ this,
return eval( code );
//go ahead and make it work side-by-side with the "real" fn.apply():
//try it as a function method:
Math.max.apply2(0, [1,2,3]); //works
//try it as a generic:
apply2.call(Math.max, 0, [1,2,3]); //works
//try it as a bound method to turn arguments into an array:
apply2.bind(Math.max, 0)([1,2,3]) // works
hmm, that a bit of typing i just did, doh!
im tryin to stop my mic-hogging.
you can "alert-ify" the Function.prototype.bind replacement on the MDC page i linked to if you want to step-through bind() like the apply2 i made above.
does that help, or did i cloud the issue further?