1

我在 JavaScript Ninja 的秘密一书中读到,如果浏览器支持,我们可以使用它document.all["id"]来获取文档中具有此类 ID 的所有元素。(尽管据说我们应该只有一个具有特定 ID 的元素)。

但是document.all返回一个HTMLAllCollection对象,我在 Chrome 中看到它有 9 个元素,比如一个数组(9 个元素,在 jsfiddle 中设置)。所以我可以理解为什么document.all[9]可以返回元素,但为什么也可以document.all["foo"]返回呢?如果我们定义var obj = { foo : 123 },那么我们可以说obj["foo"],但document.all不是一个有键的对象foo。所以据说,document.all["foo"]不应该能够返回这样的元素。

注意:这个问题不是问 的使用document.all,也不是问页面上是否有两个具有相同 ID 的元素。它询问为什么一个obj似乎没有密钥的对象foo能够使用obj["foo"] 我不知道为什么这不是一个有效的编程问题来给出一个值。

示例代码:

1 个具有此类 ID 的元素:http:
//jsfiddle.net/ArR5x/5/

2 个具有此类 ID 的元素:http:
//jsfiddle.net/ArR5x/10/

更新:丹涛是正确的。这是因为有些属性是可枚举的,有些不是,如果支持 ECMAScript 5,我们很容易产生相同的情况:http: //jsfiddle.net/Akdp9/12/这是一个关于 JavaScript 的有效问题,而真正的问题是答案是由于属性的可枚举属性。

4

3 回答 3

3

我想我明白你为什么感到困惑。让我解释几件事以消除任何混乱。其中一些您可能已经知道,但为了安全起见,我将涵盖所有这些内容。

首先,类似数组的对象仍然可以像任何其他对象一样具有属性。即使是香草Array也是这样。

var arr = [1, 2, 3];
arr.foo = "bar";
arr["foo"]; // => "bar"

因此,在解析 DOM 之后,浏览器填充与页面上每个 ID 对应的属性似乎是完全合理document.all的,即使HTMLAllCollection它更像是数组。

其次,对象的属性不一定都是一样的。您可能已经尝试过这个并注意到缺少任何“foo”属性:

Object.keys(document.all)
// => ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "length"]

但是,“foo”确实. document.all您可以很容易地验证这一点:

document.all.foo;
// => [<div id=​"foo">​hello​&lt;/div>​, <div id=​"foo">​world​&lt;/div>​]

document.all.hasOwnProperty("foo") // => true

这里的问题是它不是一个可枚举的属性。这意味着它不会出现在for/in循环中,它也解释了为什么当你全部Object.keys.

您可以使用以下propertyIsEnumerable方法确认这一点:

document.all.propertyIsEnumerable("foo"); // => false

所以说到底,这并不是一个谜。可以将任意属性分配给document.all对象,就像它们可以分配数组一样。这就是这里的情况;这些属性是不可枚举的。

于 2013-07-04T00:40:09.737 回答
2

DOM 不是在 Javascript 中实现的,并且大多数 Javascript 规则都不适用于它。

例如,在 Chrome!!document.all中,false即使在 Javascript 规则中,所有对象都是真实的。

于 2013-07-04T00:32:46.550 回答
0

仅仅因为您不应该有多个具有相同 ID 的元素并不意味着您不能查询它们。CSS 选择器将应用于具有相同 ID 的多个元素,如下所示querySelectorAll

document.querySelectorAll('#foo');

也可以返回多个元素。

这是证明它的小提琴:http: //jsfiddle.net/EgBbN/

于 2013-07-04T00:18:37.000 回答