This question already has an answer here:
- var self = this? 8 answers
I see in almost all examples of a knockout.js viewmodels the line var self = this
and then all local variables are references as self.variableName
. What is the advantage of this over using this.variableName
?
It is used for reference purposes.
this
under Javascript behaves different than in other languages. For more details look at MDN Docs on thisNormally the main reason for using this approach is to make the current
this
available to subfunctions or closures. For example:In the above calling
myObject.method
will give you the correct alert of123
. However callingmyObject.method2
will give youundefined
. This is becausethis
inside the anonymous function used withsetTimeout
does not refer tomyObject
, depending on the JavaScript interpreter it will point to different things. However, if you have:This works because the current state of
this
— at the right point — is captured, and will always referencemyObject
for every function scope that it is available to.The problem is not limited to the use of
setTimeout
. At any point where you have anonymous functions, subfunctions or closures this trick will come in handy. Sometimes people useself
, orthat
or something a bit more descriptive depending on what the current reference represents.rather than storing as a variable
There is an alternative to using
self
or any other variable to "remember" the state of this at any particular point, and that is to "bind" your anonymous or sub functions with a particular context. Many modern interpreters now support theFunction.prototype.bind
method, which can be used thusly:Calling each of the bound methods in turn would give you the following console output:
If you wish to support older browsers you can use a polyfill, or if you prefer a much simpler implementation, one that doesn't worry about binding arguments as well. The basics of what the bind code does is the following:
So, how would the initial example look using bind?
As you can see above, once bound, the returned function (closure) retains that specified context; so it can be passed around where ever you want and still keep a
this
reference to the object you want. This is useful in themethod2
example because we bundle the method up with our current context and pass it tosetTimeout
which will execute the bound method later (long after we have exited the current block execution).The same does occur for when using
self
or any other variable. The variable would be captured within the function's scope chain, and would still be there for access when the function is eventually called again. The benefit of usingbind
however is that you can override the context easily if you so wish, you would have to code your own specific methods to do so to override aself
variable.without self and bind?
It is also worth mentioning that sometimes you can achieve the same result without using
bind
at all, and instead useapply
— which should be natively available in anything you may choose to use. The major difference being that nothing is wrapped up with the function, and calling apply actually executes the function there and then with a different context — the first argument passed to apply.What is
this
?Just to elaborate this answer with further detail about
this
— before the recent comments get deleted.this
will refer to one of four things, depending on how the function you are using it within was called:The above will have a
this
ofmyObject
, unlessmethod
has had a.bind(context)
operation applied. In which casethis
will be whatever the last bound context was.Will have a
this
of the global context (usuallywindow
in browser environments), unlessunattachedFunction
has had a.bind(context)
operation applied. In which casethis
will be whatever the last bound context was.or
Both will always have a
this
ofotherObject
, because calling in this way will override any binding.Will have a
this
that refers to a new instance ofmyObject
, this will override any binding.Simple thought experiment
Taking all the above into account, what would
this
be insidereferencedMethod
?Self
is used to make sure the originalthis
is maintained within the object.This comes in handy when using event handlers and so on.
You can read more about this here
The first answer covers it basically, also it shows a good link. Check it out.