Say I have the following property method in an object:
onReady: function FlashUpload_onReady()
{
Alfresco.util.Ajax.jsonGet({
url: Alfresco.constants.PROXY_URI + "org/app/classification",
successCallback: {
fn: function (o) {
var classButtonMenu = [],
menuLabel, that = this;
var selectButtonClick = function (p_sType, p_aArgs, p_oItem) {
var sText = p_oItem.cfg.getProperty("text");
that.classificationSelectButton.set("label", sText);
};
for (var i in o.json.items) {
classButtonMenu.push({
text: o.json.items[i].classification,
value: o.json.items[i].filename,
onClick: {fn: selectButtonClick}
});
}
this.classificationSelectButton = new YAHOO.widget.Button({
id: this.id + "-appClassification",
type: "menu",
label: classButtonMenu[0].text,
name: "appClassification",
menu: classButtonMenu,
container: this.id + "-appClassificationSection-div"
});
},
scope: this
},
failureMessage: "Failed to retrieve classifications!"
});
It took me some guess work to figure out that in the selectButtonClick function that I needed to reference that instead of this in order to gain access to this.classificationSelectButton (otherwise it comes up undefined), but I’m uncertain as to why I can’t use this. My best guess is that any properties in the overall object that gets referenced within new YAHOO.widget.Button somehow looses scope once the constructor function is called.
Could someone please explain why it is that I have to reference classificationSelectButton with var that = this instead of just calling `this.classificationSelectButton’?
The most important thing to understand is that a function object does not have a fixed
thisvalue — the value ofthischanges depending on how the function is called. We say that a function is invoked with some a particularthisvalue — thethisvalue is determined at invocation time, not definition time.someFunc()),thiswill be the global object (windowin a browser) (orundefinedif the function runs in strict mode).thiswill be the calling object.callorapply,thisis specified as the first argument tocallorapply.thiswill be the element that is the target of the event.new,thiswill be a newly-created object whose prototype is set to theprototypeproperty of the constructor function.bindoperation, the function will always and forever havethisset to the first argument of thebindcall that produced it. (This is the single exception to the “functions don’t have a fixedthis” rule — functions produced bybindactually do have an immutablethis.)Using
var that = this;is a way to store thethisvalue at function definition time (rather than function execution time, whenthiscould be anything, depending on how the function was invoked). The solution here is to store the outer value ofthisin a variable (traditionally calledthatorself) which is included in the scope of the newly-defined function, because newly-defined functions have access to variables defined in their outer scope.