Javascript: passing object self reference to anonymous functions nested within multiple objects

Posted On May 29, 2009 at 2:09 pm

I know the title of this post is a little complicated but I feel it best describes the problem at hand. In Javascript, objects, arrays and variables are all technically the same thing which allows you to do some interesting stuff - such as nesting functions inside arrays inside variables inside objects inside variables. There are of course issues of scope when doing this sort of thing, though. One problem I recently came across was that I needed to reference the parent object's self from within an anonymous function that is nested within an array.

Here is some code one might initially write before realizing it will not work as intended:

SomeClassName = function() { this.ajaxError = function(textStatus) { // Do error routine } this.functionName = function(){ $.ajax({ url: "ajax.php", type: "GET", cache: false, dataType: "html", success: function(msg,textStatus) { if(textStatus == "success") { // Success routine } else { this.ajaxError(textStatus); } }, error: function(XMLHttpRequest, textStatus, errorThrown) { this.ajaxError(textStatus); } }); } }

The problem is the two instances of this.ajaxError(textStatus); within the anonymous functions. When you use a self reference inside an anonymous function, it will reference the immediate parent object in which the anonymous function was declared. In this case, this would reference to the array of settings being passed to the jQuery function. For example, if within the Success routine block of code I referenced this.url, it would return the string "ajax.php" because self is pointing to the array object.

The solution is actually quite simple but perhaps not very obvious at first (thus the reason I am bothering to write this article). Nested objects allow you to reference variables declared in any parent object (so long as they are not re-declared within the current object block). So what you do is declare a variable that points to the desired object's self. To do this, I added var objectPointer = this; immediately before the nested object code. We can then reference objectPointer from within nested objects and their anonymous functions. Here is the corrected version of the above code.

SomeClassName = function() { this.ajaxError = function(textStatus) { // Do error routine } this.functionName = function(){ var objectPointer = this; $.ajax({ url: "ajax.php", type: "GET", cache: false, dataType: "html", success: function(msg,textStatus) { if(textStatus == "success") { // Success routine } else { objectPointer.ajaxError(textStatus); } }, error: function(XMLHttpRequest, textStatus, errorThrown) { objectPointer.ajaxError(textStatus); } }); } }

This topic has the following tags: