What underlies this JavaScript idiom: var self = this?
I saw the following in the source for WebKit HTML 5 SQL Storage Notes Demo:
function Note() {
var self = this;
var note = document.createElement(‘div’);
note.className = ‘note’;
note.addEventListener(‘mousedown’, function(e) { return self.onMouseDown(e) }, false);
note.addEventListener(‘click’, function() { return self.onNoteClick() }, false);
this.note = note;
// …
}
The author uses self in some places (the function body) and this in other places (the bodies of functions defined in the argument list of methods). What’s going on? Now that I’ve noticed it once, will I start seeing it everywhere?
Solutions/Answers:
Solution 1:
See this article on alistapart.com
self
is being used to maintain a reference to the original this
even as the context is changing. It’s a technique often used in event handlers (especially in closures).
Solution 2:
I think the variable name ‘self’ should not be used this way anymore, since modern browsers provide a global variable self
pointing to the global object of either a normal window or a WebWorker.
To avoid confusion and potential conflicts, you can write var thiz = this
or var that = this
instead.
Solution 3:
Yes, you’ll see it everywhere. It’s often that = this;
.
See how self
is used inside functions called by events? Those would have their own context, so self
is used to hold the this
that came into Note()
.
The reason self
is still available to the functions, even though they can only execute after the Note()
function has finished executing, is that inner functions get the context of the outer function due to closure.
Solution 4:
It should also be noted there is an alternative Proxy pattern for maintaining a reference to the original this
in a callback if you dislike the var self = this
idiom.
As a function can be called with a given context by using function.apply
or function.call
, you can write a wrapper that returns a function that calls your function with apply
or call
using the given context. See jQuery’s proxy
function for an implementation of this pattern. Here is an example of using it:
var wrappedFunc = $.proxy(this.myFunc, this);
wrappedFunc
can then be called and will have your version of this
as the context.
Solution 5:
The variable is captured by the inline functions defined in the method. this
in the function will refer to another object. This way, you can make the function hold a reference to the this
in the outer scope.
Solution 6:
It’s a JavaScript quirk. When a function is a property of an object, more aptly called a method, this refers to the object. In the example of an event handler, the containing object is the element that triggered the event. When a standard function is invoked, this will refer to the global object. When you have nested functions as in your example, this does not relate to the context of the outer function at all. Inner functions do share scope with the containing function, so developers will use variations of var that = this
in order to preserve the this they need in the inner function.