I wonder what the standard type of the XMLHttpRequest
object is in JavaScript. I have found different results depending on the engine.
In Firefox and Chrome:
typeof XMLHttpRequest //=> "function"
In Safari:
typeof XMLHttpRequest //=> "object"
The W3C specification uses the interface
keyword to define XMLHttpRequest
, which is not used in practice:
[Constructor(optional XMLHttpRequestOptions options)]
interface XMLHttpRequest : XMLHttpRequestEventTarget {
// ...
}
The MDN definition states that:
XMLHttpRequest is a JavaScript object...
But Firefox returns "function"
, so the term is vague at least. The definition also states as for now that:
It's now being standardized in the W3C.
I have looked a bit more here and there, but no definitive answer™. Is there any?
Beyond this point, some extra background
I have just fixed a bug in this code:
if (typeof XMLHttpRequest === "function") {
// do something
}
The bug occurred only in Safari 7 so far (no test on other versions). The code works fine in Firefox and Chrome. The fix was:
if (typeof XMLHttpRequest !== "undefined") {
// do something
}
The problem came from assuming that typeof XMLHttpRequest
is the same everywhere...
Safari appears to be wrong here, according to ECMAScript 5 and the Web IDL spec. typeof XMLHttpRequest
should return "function"
.
The WebIDL spec says:
If the interface is declared with a
[Constructor]
extended attribute, then the interface object can be called as a function to create an object that implements that interface....
The internal
[[Call]]
method of the interface object behaves as follows...
Meanwhile, the specification for typeof
in the ESCAScript 5 spec has a return-value table with the entries:
Object (native or host and does implement
[[Call]]
) :"function"
Object (host and does not implement
[[Call]]
) : Implementation-defined except may not be"undefined"
,"boolean"
,"number"
, or"string"
.
From this table, we can see that any object -- native or host -- that implements [[Call]]
is required to cause typeof
to yield "function"
. The WebIDL spec requires [Constructor]
interface objects to implement [[Call]]
, so they should yield "function"
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With