remember-this
Easily create functions bound to a specific object.
Purpose
JavaScript changes the value of the this
variable depending upon how a function is invoked. For example:
var person = name: "Brian" { return thisname; } // Prints "Brian"console; var getNameDetached = persongetName; // Prints "undefined"console;
Why did it print "undefined"? Because getNameDetached
was not invoked through the person
object. Instead, it was invoked as a stand-alone function, so its this
variable was bound to JavaScript's global object. To fix this, you would instead need to do:
// Manually bind the function back to personvar getNameAttached = persongetName; // Prints "Brian"console;
In other words: you need to get the function from person
, then remember to bind it back to person
. This is easy to forget, and it can introduce some very bizarre bugs into your code.
But, good news! remember-this
provides a couple of functions that encapsulate this pattern so that your life can be awesome!
Installation
npm install remember-this
Usage
Let's pretend that I'm wiring together my routes for an Express.js application. I want the routes to call the methods (erm... functions) on my usersController
object. I can achieve this as follows:
var router = express;var usersControllers = ...; // rt stands for "Remember This"var rt = rt; // Creates the function c(funcName). It grabs// usersController[funcName] and binds it back to// usersController.var c = ; // Equivalent to:// router.get('/', usersController.index.bind(usersController));//router; // Equivalent to:// router.get('/:id', usersController.show.bind(usersController));//router;
In other words: I used the rt(...)
function to create the c(...)
function. The c(...)
function grabs methods (erm... functions) from usersController
and binds them back to usersController
.
If you want to keep the number of local variables down to a minimum, then you can pass a callback to the rt(...)
function instead. For example:
var router = express;var usersControllers = ...; // rt stands for "Remember This"var rt = rt; ;
Or, maybe your usersController
only contains 1 method that you want to pass to your router. In that case, you can use the bound
function instead:
var router = express;var usersControllers = ...; var bound = bound; router;