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");
morgan.logger = function() {
var self = this;
return function() {
console.log(self);
};
};
morgan.logger = function() {
var that = this;
return function() {
console.log(that);
};
};
morgan.logger = function() {
var _this = this;
return function() {
console.log(_this);
};
};
morgan.logger = function() {
var person = this;
return function() {
console.log(person);
};
};
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!");
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.
See tl;dr ;)
Great write up!
We went with
_this
in our style guide because it means you don't have to jump back up to the top of the function to the variable assignment to verify that it was a reference to the outer scopethis
. But I can see how naming the saved reference could be more useful than saving you the time of jumping back to the top.The important part is consistency. Nothing's worse than some folks on the team naming their saved reference while others use
self
and others usethat
.Bind is great too! We didn't mention bind in the style guide because we just wanted to address how to store a reference to
this
, but this is specific to Airbnb code only because our legacy JavaScript doesn't use bind anywhere so we have a lot ofvar [self | that | _this] = this;
floating around.Hope that clears up why we went with
_this
and feel free to open an issue on the style guide we love feedback from the community and welcome pull requests!