Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the type of XMLHttpRequest in JavaScript?

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


Context of the question

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...

like image 561
Eric Platon Avatar asked Jun 09 '15 01:06

Eric Platon


1 Answers

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".

like image 99
apsillers Avatar answered Oct 31 '22 16:10

apsillers