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
call
andapply
and why.bind
was 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 = this
pattern but doesn't really suggest pros and cons
- Explains the
- Understanding JavaScript’s Function.prototype.bind
- Says
self = this
is fine, but explains how.bind
works 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
, withcontext
often 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 = this
idiom.They might not be aware of what
.bind
does too; but they can copy-paste & find a more straightforward MDN documentation for it.Specifically,
.bind
ing a function makes it clear:In this,
bind
is 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 = this
is when I need multiple contexts inside a callback; but in most of my use-cases I tend to resolve that by accessingevent.target
as second context, and still keepthis
bound 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.