JavaScript中的XMLHttpRequest类型是什么?

6
我想知道在JavaScript中,XMLHttpRequest对象的标准类型是什么。我发现不同的引擎会有不同的结果。
在Firefox和Chrome中:
typeof XMLHttpRequest //=> "function"

在Safari中:
typeof XMLHttpRequest //=> "object"

W3C规范使用"interface"关键字来定义XMLHttpRequest,但实际上并未被使用
[Constructor(optional XMLHttpRequestOptions options)]
interface XMLHttpRequest : XMLHttpRequestEventTarget {
  // ...
}

MDN定义指出:

XMLHttpRequest是一个JavaScript对象...

但是Firefox返回"function",因此该术语至少是模糊的。该定义还指出,目前正在W3C中进行标准化:

它现在正在W3C中标准化。

我已经在这里和那里查看了一些信息,但没有明确的答案™。有吗?

超出这个点,一些额外的背景


问题背景

我刚刚修复了这段代码中的一个错误:

if (typeof XMLHttpRequest === "function") {
  // do something
}

这个 bug 目前只出现在 Safari 7 上(没有测试其他版本)。代码在 Firefox 和 Chrome 中运行良好。修复方法如下:
if (typeof XMLHttpRequest !== "undefined") {
  // do something
}

问题在于假设 typeof XMLHttpRequest 在任何地方都是相同的...

1
不是直接相关的,但如果未定义XMLHttpRequestXMLHttpRequest || ActiveXObject会抛出一个ReferenceError吗? - Alexander O'Mara
1
@jfriend00:这就是OP所说的-在Safari中,它奇怪地不是一个函数。XMLHttpRequest instanceof Function === false。我一直认为构造函数必须是一个函数。(已验证,Safari 8.0.6) - Amadan
4
主机对象有时会遵循奇怪的规则,似乎没有很强的标准化。它们不是纯 JavaScript 对象 - 它们是通过 JavaScript 公开的主机对象。解决方法是不要假设它是一个特定类型并测试是否不为undefined - jfriend00
2
@jfriend00:这不是事实吗。最新消息:浏览器存在不兼容性。 :P - Amadan
1
似乎在Safari中,所有本地构造函数都是这种情况; typeof Imagetypeof Locationtypeof History都是“object”。我不知道它是否相关,但在Safari中,constructor__proto__属性是一个普通的Object构造函数/实例,而在Firefox中则是一个构造函数。 - Alexander O'Mara
显示剩余5条评论
2个回答

3

根据 ECMAScript 5 和 Web IDL 规范,Safari 在这里似乎有误。 typeof XMLHttpRequest 应该返回 "function"

WebIDL 规范 指出:

如果接口声明带有 [Constructor] 扩展属性,则可以将接口对象调用为函数以创建实现该接口的对象。

...

接口对象的内部 [[Call]] 方法的行为如下...

同时,ESMAScript 5 规范中 typeof 的规定 中有一个返回值表,其中包含以下条目:

对象(本地或宿主并实现 [[Call]]): "function"

对象(宿主并未实现 [[Call]]):实现定义,除了可能不是 "undefined""boolean""number""string"

从这个表格中,我们可以看到任何实现 [[Call]] 的对象(本地或宿主)都需要导致 typeof 返回 "function"。WebIDL 规范要求 [Constructor] 接口对象实现 [[Call]],因此它们应该返回 "function"


是的,Safari 又出现了另一个主机对象 bug。 - Bergi

1
如果您只是想检查XMLHttpRequest是否存在,则可以使用以下代码:
if (typeof XMLHttpRequest !== "undefined") {
  // do something
}

or

if (window.XMLHttpRequest !== undefined) {
  // do something
}

or

if (this.XMLHttpRequest !== undefined) {
  // do something
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接