In Javascript this is bound in unexpected ways. Functions, in particular, create a new 'this' and so when you want to keep a reference to an "outer" object you sometimes see the pattern:
var self = this;
as in:
var self = this;
return function(whatever) {
return self.foo(whatever); // `this` here is for the inner function
}Is this a good pattern? Shouldn't we just use .bind(this) on the inner function?
I've done some reasearch and here are a few links that discuss this idea along with a little summary of what they suggest.
- Is var self = this; a bad pattern?
- Do what feels right
- What underlies this JavaScript idiom: var self = this?
- Find to do, but could be dangerous because there is a
window.self- see also: Window.self
- Find to do, but could be dangerous because there is a
- Getting Out of Binding Situations in JavaScript
- Tutorial on binding-sensitive code patterns, using
callandapplyand why.bindwas created
- Tutorial on binding-sensitive code patterns, using
- var self = lame
- This fellow doesn't care for the idiom, but I don't find his arguments convincing
- self = this
- Explains the
self = thispattern but doesn't really suggest pros and cons
- Explains the
- Understanding JavaScript’s Function.prototype.bind
- Says
self = thisis fine, but explains how.bindworks and why to use it
- Says
- Using var self = this or .bind(this)?
- Provides a good list of pros and cons to using
.bind
- Provides a good list of pros and cons to using
- Tweets:
- Ohhhh I would do anything for scope, but I won't do that = this — Jake Archibald (@jaffathecake) February 20, 2013
- @benhowdle $this for jQuery, for plain JS i don't, use .bind() — Sindre Sorhus (@sindresorhus) February 22, 2013
To me, it seems that .bind definitely has it's place. For instance when you have a function in a variable and you want to attach it to a particular this.
That said, in the case of nested anonymous functions I think that using var self = this; is straightforward and requires less mental accounting vs. using .bind. For example, say we have two nested functions:
function foo() {
return (function() {
doSomething((function() {
return this.name; // what is `this` again?
}).bind(this));
}).bind(this);
}vs.
function foo() {
var self = this;
return (function() {
doSomething((function() {
return self.name; // `self` is easy to know because its defined
})
})
}Of course, because this is a matter of style the issue of "mental accounting" will differ from person to person. But to me, given the semtanics of Javascript's this, I think that self = this is easy to comprehend when you have nested callbacks.
IMHO, being explicit using
bind()is more understandable than a more-cryptic & non-standardcontext = this, withcontextoften varying amongself,that,thisArg,context, 'ctx'.The reassignment as variable doesn't express a clear intention, because its reason to be lies in an implicit implementation detail (as it often happens in Javascript 😓): the closure.
New JS devs aren't necessarily aware of closures and about the
self = thisidiom.They might not be aware of what
.binddoes too; but they can copy-paste & find a more straightforward MDN documentation for it.Specifically,
.binding a function makes it clear:In this,
bindis unbeatable for clarity and code sharing. Also it is more straightforward to trace, debug & refactor, for developers of any level of experience.I tend to prefer it as a habit, even when it's inconvenient, because it feels cleaner, more structured, and less obscure.
Only case where I might use
var self = thisis when I need multiple contexts inside a callback; but in most of my use-cases I tend to resolve that by accessingevent.targetas second context, and still keepthisbound via.bind, without having to get anything from the outer scope.Example
Of course the choice depends also on how the script code is being structured.