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.
Naming this in nested functions
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 ;)
under 'Another more realistic example' you have a timer variable which you pass into clearTimeout but you never assign it...