Last active
December 25, 2015 18:59
-
-
Save joladev/7024122 to your computer and use it in GitHub Desktop.
JavaScript Bind 101
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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