Reputation:
I'm going through a book on DOM scripting and the following function appears within the book when they talk about Ajax.
function getHTTPObject() {
if(typeof XMLHTTPRequest == "undefined")
XMLHTTPRequest = function() {
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0");}
catch(e) {}
//several more fall through try/catch blocks attempting
//to create different XMLHTTP objects.
//If none succeed...
return false;
}
return new XMLHTTPRequest();
}
If the new keyword is used within the try/catch block when attempting to create the ActiveXObject within the inner anonymous function that is assigned to XMLHTTPRequest, why is the new keyword used again when returning the result of XMLHTTPRequest at the end of getHTTPObject()?
It seems like it's returning a new, new object.
Edit
I understand broadly what the purpose of the code is, to check if the XMLHTTPRequest constructor exists, and if not define one that tries to make XMLHTTP ActiveXObjects. I'm with you this far.
Supposing XMLHTTPRequest is undefined.
XMLHTTPRequest is assigned the inner function constructor.
Then at the bottom of getHTTPRequest XMLHTTPRequest is called.
Within XMLHTTPRequest, a new ActiveXObject is created and returned to the caller, in this case getHTTPObject. Now getHTTPObject in turn returns this object out to it's caller. But again, why does the line:
return new XMLHTTPRequest()
need that new there if the new (i.e. object instantiation) already occurs within the code of that try block inside of the defintion / scope of XMLHTTPRequest()? Why not simply:
return XMLHTTPRequest()
Thanks everyone for the answers. It's very possible, likely even, that I just don't have a strong enough grasp of JS constructor syntax and that's what's tripping me up here.
Upvotes: 0
Views: 323
Reputation: 173552
JavaScript allows returning another object from its constructor; the constructor is defined here:
XMLHTTPRequest = function() {
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0");}
In the case that new ActiveXObject("Msxml2.XMLHTTP.6.0")
succeeds, the resulting object gets returned to any caller that invoked XMLHTTPRequest
as a constructor.
return false;
This statement will just return an empty object of type XMLHTTPRequest
because false
is not an object itself.
At the end getHTTPObject()
needs to return an object, not just the constructor, which is why you see return new XMLHTTPRequest();
at the end.
See also the dry version of this behaviour from the ECMAScript Language Specification.
Upvotes: 0
Reputation: 66
The try block you have mentioned is executed only when the if condition
if(typeof XMLHTTPRequest == "undefined")
holds good.If not, it reaches the return statement at the end of getHTTPObject()
method directly and then returns the new XMLHTTPRequest
object.
So, either new ActiveXObject
or new XMLHTTPRequest
are returned.
Upvotes: 1
Reputation: 147363
You have misunderstood the code.
> function getHTTPObject() {
>
> if(typeof XMLHTTPRequest == "undefined")
> XMLHTTPRequest = function() {
If the identifier XMLHTTPRequest
is undefined, assign the following function.
> try { return new ActiveXObject("Msxml2.XMLHTTP.6.0");}
> catch(e) {}
>
> //several more fall through try/catch blocks attempting
> //to create different XMLHTTP objects.
> //If none succeed...
>
> return false;
> }
Now call XMLHttpRequest, which will be the host provided function or the one assigned above.
> return new XMLHTTPRequest(); }
The above assumes that if the identifier XMLHttpRequest resolves to something other than undefined, that it is callable and returns an XMLHttpRequest
instance.
Upvotes: 1
Reputation: 27277
The inner constructor is not called before the outer constructor. Instead, the XMLHTTPRequest function is first defined if it does not exist and then called as a constructor.
It first checks if XMLHTTPRequest exists (either the native one, or one from the previous invocation. If it does, it is called as a constructor. If not, it is created first.
One trick here is that if a constructor returns an object, the new
object is not the one that got allocated, but the one that got returned. Normally, this causes an immediate garbage collection. A smart interpreter may realise it doesn't need to allocate at all. This is what the newly created constructor does - return a different object.
(see http://www.gibdon.com/2008/08/javascript-constructor-return-value.html)
The created XMLHTTPRequest replaces the browser's one. The browser's own XMLHTTPRequest constructor cannot be called as a function and needs to be called as a constructor, which is why the newly created object must be called as a constructor as well.
Note that this is normally the job of a library or a toolkit, such as jQuery, to pick the correct AJAX object.
Upvotes: 0
Reputation: 1095
Return happens immediately and exits the code block. Only one of those returns will get hit.
Upvotes: 1