Naming this in nested functions (original) (raw)
tl;dr
If you must nest functions in a way that requires access to multiple this', alias outer this to something meaningful - describe the value it's holding. Treat this as the invisible first argument.
In general though, avoiding the situation (nested functions and frivolous use of this
) will frequently produce clearer results.
I was accidentally included in a discussion on how to best name this in nested functions in JavaScript. +1's were given to this suggestion of using _this.
Giving style advice on naming nested this
without a meaningful context isn't too helpful in my opinion. Examples below have been altered to have at least some context, although a completely contrived and stupid one.
Assume this setup:
var morgan = new Person("Morgan");
Bad
morgan.logger = function() { var self = this; return function() { console.log(self); }; };
Bad
morgan.logger = function() { var that = this; return function() { console.log(that); }; };
Bad (still no good in my opinion)
morgan.logger = function() { var _this = this; return function() { console.log(_this); }; };
Meaningful name: Better
morgan.logger = function() { var person = this; return function() { console.log(person); }; };
Another more realistic example
Function.prototype.throttle = function (ms) { var fn = this; var timer; return function () { clearTimeout(timer); var args = [].slice.call(arguments); timer = setTimeout(function () { fn.apply(this, args); }, ms || 100); }; };
function myFunc() { console.log(arguments); }
var throttled = myFunc.throttle(50); throttled("Hey there!");
In the above example, "fn" is way superior to "_this". Still, the following example would be even better:
function throttle(fn, ms) { var timer; return function () { clearTimeout(timer); var args = [].slice.call(arguments); timer = setTimeout(function () { fn.apply(this, args); }, ms || 100); }; };
function myFunc() { console.log(arguments); }
var throttled = throttle(myFunc, 50); throttled("Hey"); throttled("Hey there!");
What about bind
?
In cases where you don't also need the nested this
bind
works fine. However, since the bind happens on the bottom, it can also create quite confusing results. I also think the massive use of the word this
in code that binds a lot - see most jQuery code snippets - is very confusing. Naming each thing is generally more readable in my opinion.
If using bind
, I generally prefer a separate bind
over the Function.prototype
one, e.g.:
morgan.logger = function () { return bind(this, function() { console.log(this); }); };
Because it moves the target object up. "object, method" is also less noisy than "object.method, object".
However, this example can be even better written like so:
morgan.logger = function () { return bind(console.log, console, this); };
i.e., with added partial application. With the non-Function.prototype
bind
, you can even do one better, like so:
morgan.logger = function () { return bind(console, "log", this); };
In my opinion, this is pretty concise and readable. I think lodash's bind
supports this kind of use.
In summary
See tl;dr ;)