[英]In JavaScript, how does an object “obj” that doesn't have the property named “foo” be able to give a value using obj[“foo”]?
I read in the book Secrets of the JavaScript Ninja, that we can use document.all["id"]
to get all elements in the document that has such ID, if the browser supports it. 我在《 JavaScript忍者的秘密》一书中读到,如果浏览器支持的话,我们可以使用
document.all["id"]
获取具有此类ID的文档中的所有元素。 (although supposedly we should only have one element with a particular ID). (尽管据说我们应该只有一个具有特定ID的元素)。
But document.all
returns an HTMLAllCollection
object, and I see in Chrome that it has 9 elements, like an array (9 elements, as set up in jsfiddle). 但是
document.all
返回一个HTMLAllCollection
对象,我在Chrome浏览器中看到它有9个元素,如数组(9个元素,在jsfiddle中设置)。 So I can understand why document.all[9]
can return the element, but why can document.all["foo"]
return it too? 这样我就能理解为什么
document.all[9]
可以返回元素,但是为什么document.all["foo"]
也可以返回元素? If we define var obj = { foo : 123 }
, then we can say obj["foo"]
, but document.all
is not an object with a key foo
. 如果我们定义
var obj = { foo : 123 }
,那么我们可以说obj["foo"]
,但是document.all
不是带有键foo
的对象。 So supposedly, document.all["foo"]
shouldn't be able to return an element like that. 因此,据推测,
document.all["foo"]
不能返回这样的元素。
Note: this question is not to ask about the use of document.all
, and it is not about asking to have two elements with the same ID on the page. 注意:此问题不是要询问
document.all
的使用,也不是要在页面上询问两个具有相同ID的元素。 It is asking why an object obj
that does not seem to have the key foo
is able to give a value using obj["foo"]
I do not know why this is not a valid programming question. 这是在问为什么似乎没有键
foo
的对象obj
能够使用obj["foo"]
给出值,我不知道为什么这不是有效的编程问题。
sample code: 样例代码:
1 element with such ID: 1个具有以下ID的元素:
http://jsfiddle.net/ArR5x/5/ http://jsfiddle.net/ArR5x/5/
2 elements with such ID: 2个具有此类ID的元素:
http://jsfiddle.net/ArR5x/10/ http://jsfiddle.net/ArR5x/10/
Update: Dan Tao is correct. 更新:丹涛是正确的。 It is due to some properties being enumerable and some are not, and we can easily produce the same situation if ECMAScript 5 is supported: http://jsfiddle.net/Akdp9/12/ The is a valid question about JavaScript, and the real answer is that it is due to the enumerable attribute of a property.
这是由于某些属性是可枚举的,而有些则不是,如果支持ECMAScript 5,我们可以很容易地产生相同的情况: http : //jsfiddle.net/Akdp9/12/这是关于JavaScript的有效问题,而真正的答案是由于属性的可枚举属性。
I think I understand why you're confused. 我想我理解您为什么感到困惑。 Let me explain a couple of things to clear up any confusion.
让我解释一些事情以消除任何混乱。 Some of this you may already know, but I'm going to cover all of it just to be safe.
您可能已经知道其中一些内容,但是为了安全起见,我将介绍所有这些内容。
First, an array-like object can still have properties just like any other object. 首先,类似数组的对象仍然可以像其他任何对象一样具有属性。 Even a vanilla
Array
is like this. 甚至香草
Array
都是这样。
var arr = [1, 2, 3];
arr.foo = "bar";
arr["foo"]; // => "bar"
So it seems perfectly reasonable that after parsing the DOM, the browser populates document.all
with properties corresponding to every ID on the page, even though HTMLAllCollection
is rather array-like. 因此,在解析DOM之后,即使
HTMLAllCollection
非常类似于数组,浏览器在对document.all
进行填充时,都具有与页面上每个ID对应的属性,这似乎是完全合理的。
Second, an object's properties are not necessarily all created equal. 其次,对象的属性不一定都相同。 You may have tried this and noticed a lack of any "foo" property:
您可能已经尝试过此操作,但发现缺少任何“ foo”属性:
Object.keys(document.all)
// => ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "length"]
However, "foo" really is a property of document.all
. 但是,“ foo”确实是
document.all
的属性。 You can verify that pretty easily: 您可以很容易地验证这一点:
document.all.foo;
// => [<div id="foo">hello</div>, <div id="foo">world</div>]
document.all.hasOwnProperty("foo") // => true
The issue here is that it is not an enumerable property. 这里的问题在于它不是枚举属性。 This means it won't show up in a
for
/ in
loop, and it also explains why you don't see it when you all Object.keys
. 这意味着它不会出现在
for
/ in
循环中,并且还解释了为什么当您使用所有Object.keys
时都看不到它。
You can confirm this with the propertyIsEnumerable
method : 您可以使用
propertyIsEnumerable
方法进行确认:
document.all.propertyIsEnumerable("foo"); // => false
So in the end it's not so much of a mystery. 因此,最后并不是一个谜。 Arbitrary properties can be assigned to the
document.all
object, just as they can with arrays. 可以将任意属性分配给
document.all
对象,就像使用数组一样。 And that is the case here; 就是这种情况。 the properties just aren't enumerable.
这些属性是无法枚举的。
DOM is not implemented in Javascript and most rules of Javascript don't apply to it. DOM不是用Javascript实现的,大多数Javascript规则都不适用于它。
For example, in Chrome !!document.all
evaluates to false
even though in Javascript rules, all objects are truthy. 例如,在Chrome
!!document.all
计算结果为false
,即使在Javascript中的规则,所有的对象都是truthy。
Just because you aren't supposed to have multiple elements with the same ID does not mean that you can't query them. 仅仅因为您不应该拥有多个具有相同ID的元素,并不意味着您无法查询它们。 A CSS selector will apply to multiple elements with the same ID, as will
querySelectorAll
: CSS选择器将应用于具有相同ID的多个元素,以及
querySelectorAll
:
document.querySelectorAll('#foo');
can also return multiple elements. 也可以返回多个元素。
Here's the fiddle to prove it: http://jsfiddle.net/EgBbN/ 这是证明它的小提琴: http : //jsfiddle.net/EgBbN/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.