Skip to content

Instantly share code, notes, and snippets.

@joladev
Last active December 25, 2015 18:59
Show Gist options
  • Save joladev/7024122 to your computer and use it in GitHub Desktop.
Save joladev/7024122 to your computer and use it in GitHub Desktop.
JavaScript Bind 101
// Set up a simple object to use as "context"
var context = { foo: "bar" };
// A function that uses a reference to a variable called "foo".
function returnFoo () {
return this.foo;
}
// This variable does not exist on scope, so is undefined.
returnFoo(); // => undefined
// But if we bind the function to the context.
var bound = returnFoo.bind(context);
// The name variable is now in scope.
bound(); // => "bar"
//
// If you enjoyed that, keep reading. It just gets better.
//
// There are many ways of attaching a context to a function.
returnFoo.call(context); // => bar
returnFoo.apply(context, []); // => bar
// Including adding the function to the object.
context.returnFoo = returnFoo;
context.returnFoo(); // => bar
// Now let's get freaky with it.
var slice = Array.prototype.slice;
// slice is now unbound. As Array.prototype.slice usually
// acts on the context it is given, or "this", it will
// no longer work.
slice([1,2,3], 0, 1); // => TypeError: can't convert undefined to object
// But if we take an example from above.
slice.call([1,2,3], 0, 1); // => [1]
// Apply works like call, but takes arguments as an array.
slice.apply([1,2,3], [0,1]); // => [1]
// It sure gets old using .call though. What if we bind it?
// Let me just say that again. Let's bind "calL" to slice. Yes.
slice = Function.prototype.call.bind(Array.prototype.slice);
// Now slice uses the first argument as context.
slice([1,2,3], 0, 1); // => [1]
//
// Pretty cool huh? But I got one last thing for you.
// This will mess your brain up.
//
// Let's put "bind" itself through the same process
// as we did "slice".
var bind = Function.prototype.call.bind(Function.prototype.bind);
// Wrap your mind around that. Think about it.
// What does it do? We are flipping "call",
// returning a function that takes a function
// and a context and returning a fully bound function.
// I know, that probably didn't help. It took me a while.
// Bringing back our original example.
var context = { foo: "bar" };
function returnFoo () {
return this.foo;
}
// And using our new amazing "bind".
var incredible = bind(returnFoo, context);
incredible(); // => bar
// Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment