Twitter上有这条推文:
在 JavaScript 中,所有对象都是真实的(根据规范)。在 DOM 中,这条规则有一个例外。它是什么?#jsquiz #fronttrends
有人知道答案吗?
免责声明: 我是发推文的人 :)这是我会在我的前沿趋势演讲中提出和回答的问题。我在上台前 5 分钟写了那条推文。
由于 Twitter 上有 140 个字符的限制,这个问题有点含糊。我问的真正问题如下。
ECMAScript 规范定义ToBoolean()
如下:
如您所见,所有非原始对象(即所有不是布尔值、数字、字符串、undefined
或null
的对象)按照规范都是真实的。然而,在 DOM 中,有一个例外——一个虚假的 DOM 对象。你知道那是哪一个吗?答案是document.all
。HTML 规范说:
该
all
属性必须返回一个HTMLAllCollection
根节点Document
,其过滤器匹配所有元素。为 all 返回的对象有几个异常行为:
用户代理必须像
ToBoolean()
JavaScript 中的运算符将返回的对象转换为all
值false
一样。对于JavaScript中的
==
and运算符,用户代理必须表现得好像返回的对象等于该 值。!=
all
undefined
用户代理必须采取行动,以便 JavaScript 中的运算符在应用于返回的对象时
typeof
返回字符串。'undefined'
all
这些要求故意违反了撰写本文时的 JavaScript 规范(ECMAScript 第 5 版)。JavaScript 规范要求
ToBoolean()
运算符将所有对象转换为true
值,并且没有规定对象的行为就好像它们是undefined
为了某些运算符的目的一样。这种违规的动机是希望与两类遗留内容兼容:一种使用存在document.all
作为检测遗留用户代理的一种方式,一种只支持那些遗留用户代理并使用document.all
对象而不首先测试其存在.
所以,document.all
是这个 ECMAScript 规则的唯一官方例外。(在 Operadocument.attachEvent
等中也是虚假的,但在任何地方都没有指定。)
它是document.all
。
它是非标准的,所以你最好使用document.getElementsByTagName("*")
.
好的,使用此代码
for (var name in document) {
if (!!document[name] === false && typeof document[name] === 'object' && document.hasOwnProperty(name)) {
$('#foo').append('document.' + name + '<br />');
};
};
我在 chrome 中得到了这个结果(结果可能会有所不同)
document.ownerDocument
document.attributes
document.namespaceURI
document.nextSibling
document.webkitCurrentFullScreenElement
document.nodeValue
document.preferredStylesheetSet
document.textContent
document.previousSibling
document.parentNode
document.xmlVersion
document.parentElement
document.localName
document.selectedStylesheetSet
document.prefix
document.xmlEncoding