Note: please keep in mind that this is not a generic question on the use of this on javascript. This is about aspect.around malfunctioning (it’s meant to set the scope for the call, and it doesn’t). The question is: why is aspect.around malfunctioning? this question needs you to read carefully how to reproduce and do so with the fiddle provided!
I had to shred my app to pieces in order to make the problem fit in a fiddle.
So here it is:
http://jsfiddle.net/mercmobily/THtsv/1/
It’s a simple form, with validation:
- Type something in the textbox: the validation method of the widget will be called.
- Then press the submit button: validation will fail, and aspect.around will be called to wrap something around the validation method.
- At that point, try to type anything in the textbox again: It will come back with an error, as the validator will fail because of “this” being set to “window” instead of the widget.
So, once the aspect is added, the validator stops working. Basically, the value of “this” gets lost. Now:
-
aspect.around() is meant to run the new validator in the right scope (obviously) and it’s failing to do so
-
I can “fix” this problem by changing the call to the validator into this:
return originalValidator.call(this, value);However, it doesn’t answer the question “Why is ‘this’ lost?” -
If you backtrace the code, you will see that aspect.around() is doing what it normally does… but it must be doing something wrong
So, the question: why is dojo.around() malfunctioning, not setting this to the passed object’s scope?
Merc.
It is not very easy to follow what exactly you’re asking. From your jsFiddle, I see this comment so I’ll attempt to answer the question you pose here:
The answer to why you need the
.callhere in order to preserve the value ofthisis as I described below in the generic description of howthisworks when making a function call.When you make an ordinary function call as in this statement:
The value of
thisis set back towindow. That’s how javascript works. If you want to preserve the current value ofthisin that function, you have to specify that you want a particular value ofthisset using.call()or.apply()or anobj.method()call. The value ofthisin an ordinary function call is NOT bound to the function. It’s set by the caller and can be anything the caller wants. If you don’t specify it, then javascript setsthistowindowand that is exactly what is happening in your code.Here’s the generic description of how the value of
thisis set and this generic description applies in your specific case.The simple rule is that the value of
thisis reset on every single function call in javascript. If it’s just a plain function call, thenthisis set to the global object (which iswindowin the browser environment). So any simple function call will always setthistowindow.If you make a method call like
obj.method(), thenthiswill be set to point to theobjwhile in themethod().If you use
func.apply(a, b)orfunc.call(a, b)then you can explicitly control whatthisis set to via the value of the first argument to.apply()or.call(). See this MDN doc here or here for more info on.call()and.apply().