views:

65

answers:

3

So I'm reading a book on AJAX, and they are talking about using inner function as a way to handle multiple requests. I understand that, but in this bit of code they used, I don't understand how the variable XMLHttpRequestObject can still be used:

if(XMLHttpRequestObject) 
{
    XMLHttpRequestObject.open(“GET”, dataSource);

    XMLHttpRequestObject.onreadystatechange = function()
    {
        if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) 
        {
            document.getElementById(“targetDiv”).innerHTML = XMLHttpRequestObject.responseText;
            delete XMLHttpRequestObject;
            XMLHttpRequestObject = null;
        }
    }

    XMLHttpRequestObject.send(null);
}

My first qualm is when they delete XMLHttpRequestObject and then, after it's supposedly deleted, they set it equal to null. Then after it supposedly deleted and set to null, they use the XMLHttpRequestObject.send(null); But how does it do anything when XMLHttpRequestObject is deleted and/or contains no value since it's also set to null?

+2  A: 

The onreadystatechange function doesn't execute immediately when it is created. As the name suggests, it is called when the state changes.

In this case the XMLHttpRequestObject is only deleted after XMLHttpRequestObject.readyState == 4 and XMLHttpRequestObject.status == 200, i.e. after the page is successfully received.

Mark Byers
Ok, so once it is successfully received, how does it not raise an error. It still sets the XMLHttpRequestObject equal to null after deleting it. Are things just different with the delete keyword in JS as compared to C++ or something?
Justen
@Justen: what happens at the `delete` statement is that whatever object is referenced by the variable with the name `XMLHttpRequestObject` is marked for delete and will eventually be garbage collected. The `null` assignment is just giving the variable `XMLHttpRequestObject` a new value - `null`. So the variable `XMLHttpRequestObject` is not the same as the object - it's just used to hold the reference to an object, and `delete` acts on that object, not the variable.
Roland Bouman
I thought that JS had garbage collection? Why the need to mark the thing for deletion ourselves?
Justen
Justen, JS indeed has garbage collection. But even then, you can help by explictly telling the machine you don't need an object anymore. I think that is the intention of those lines. In addition, there are known bugs in f.e. internet explorer with the JS wrapped presentation of host objects like the DOM and I believe also the XHR. See: http://www.jibbering.com/faq/faq_notes/closures.html#clMem I think it's likely that these lines are intended to fight that issue
Roland Bouman
A: 

It sets up a function to be called when the state changes. That isn't called immediately, so it isn't using the object right away.

The fact that you can use the XmlHttpRequestedObject inside is some fancy compiler trickery, basically, where it writes the ugly code to wrap the function and variable stuff.

Andrew Backer
So it doesn't use it instantly, but when it is used, all my questions are the same.
Justen
+1  A: 

My first qualm is when they delete XMLHttpRequestObject and then, after it's supposedly deleted, they set it equal to null.

Don't know why they're doing that. Setting to null seems sufficient to me, but perhaps this solves some obscure browser quirk.

Then after it supposedly deleted and set to null, they use the XMLHttpRequestObject.send(null);

no. the deleting takes place inside the event handler - this event handler function is not called until after the request is done, and the state of the xhr object changes, for example due to the server sending the response, or an error occurring in the communication.

Basically, the calling sequence is not the same as the declaration sequence. The calling sequence is:

XMLHttpRequestObject.open(“GET”, dataSource);
... //assign event handler so it can be called later on
XMLHttpRequestObject.send(null); 
... //request send, program continues


//separate context here, goes off when the readystate of the xhr changes
//due to server response or error:
function()
{
    if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) 
    {
        document.getElementById(“targetDiv”).innerHTML = XMLHttpRequestObject.responseText;
        delete XMLHttpRequestObject;
        XMLHttpRequestObject = null;
    }
}
Roland Bouman