在 JavaScript 中,没有名为 "foo" 的属性的对象"obj"如何使用 obj[ "foo" ] 给出值?



我在《JavaScript忍者的秘密》一书中读到,如果浏览器支持,我们可以使用document.all["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相同的元素。它在问为什么一个似乎没有密钥foo的对象obj能够使用obj["foo"]给出一个值。我不知道为什么这不是一个有效的编程问题

示例代码:

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

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

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

我想我理解你为什么感到困惑。让我解释几件事来澄清任何困惑。其中一些你可能已经知道了,但为了安全起见,我会报道所有这些。

首先,类似数组的对象仍然可以像其他对象一样具有属性。即使是香草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​</div>​, <div id=​"foo">​world​</div>​]
document.all.hasOwnProperty("foo") // => true

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

您可以使用propertyIsEnumerable方法确认:

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

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

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

例如,在Chrome中,!!document.all的计算结果为false,即使在Javascript规则中,所有对象都是truthy。

不应该有多个具有相同ID的元素,并不意味着不能查询它们。CSS选择器将应用于具有相同ID的多个元素,querySelectorAll:也是如此

document.querySelectorAll('#foo');

也可以返回多个元素。

以下是证明这一点的小提琴:http://jsfiddle.net/EgBbN/

最新更新