JavaScript 循环:for...in 与 for
我在 Javascript 中遇到了一个奇怪的行为。我明白了
“对象不支持此属性或方法”
以下代码中的 removeAttribute
函数出现异常:
var buttons = controlDiv.getElementsByTagName("button");
for ( var button in buttons )
button.removeAttribute('disabled');
当我使用以下代码更改代码时,问题消失:
var buttons = controlDiv.getElementsByTagName("button");
for ( var i = 0; i < buttons.length; i++ )
buttons[i].removeAttribute('disabled');
for.properties 中的
?button
的值是多少? ..在
I faced a strange behaviour in Javascript. I get
"Object doesn't support this property or method"
exception for the removeAttribute
function in the following code:
var buttons = controlDiv.getElementsByTagName("button");
for ( var button in buttons )
button.removeAttribute('disabled');
When I change the code with the following, the problem disappears:
var buttons = controlDiv.getElementsByTagName("button");
for ( var i = 0; i < buttons.length; i++ )
buttons[i].removeAttribute('disabled');
What is the value of button
inside the for...in
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
虽然 for..in 通常不应该用于数组,但是在 ES5 之前,存在将其与稀疏数组一起使用的情况。
正如其他答案中所述,for..in 和数组的主要问题是:
[[Prototype]]
链上的那些。这会导致性能降低,因为可能需要进行 hasOwnProperty 测试以避免继承属性。在 ES5 之前使用 for..in 的原因之一是提高稀疏数组的性能(只要顺序无关紧要)。例如,在下面的例子中:
使用 for..in 迭代a将比使用 for 循环快得多,因为它只会访问两个属性,而 for 循环将尝试 1001。
但是,这个ES5 的 forEach 使 case 变得多余,它只访问存在的成员,因此:
也只会按顺序迭代两个属性。
While for..in should not generally be used for Arrays, however prior to ES5 there was a case for using it with sparse arrays.
As noted in other answers, the primary issues with for..in and Arrays are:
[[Prototype]]
chain. This leads to lower performance as a hasOwnProperty test is probably required to avoid inherited properties.One reason to use for..in prior to ES5 was to improve performance with sparse arrays, provided order doesn't matter. For example, in the following:
Iterating over a using for..in will be much faster than using a for loop, as it will only visit two properties whereas a for loop will try 1001.
However, this case is made redundant by ES5's forEach, which only visits members that exist, so:
will also only iterate over two properties, in order.
for...in
用于循环访问对象的属性。但它的工作方式与普通的 for 循环相同:循环变量包含当前的“索引”,即对象的属性而不是值。要迭代数组,您应该使用普通的
for
循环。buttons
不是一个数组,而是一个NodeList
(类似数组的结构)。如果使用
for...in
迭代buttons
with:您将看到它输出类似以下内容:
because
length
anditem< /code> 是
NodeList
类型的对象的两个属性。因此,如果您天真地使用for..in
,您将尝试访问buttons['length'].removeAttribute()
,这将引发错误Buttons['length']
是一个函数,而不是 DOM 元素。所以正确的方法是使用普通的
for
循环。但还有另一个问题:NodeList
是实时的,这意味着每当您访问length
时,列表都会更新(再次搜索元素)。因此,您应该避免不必要地调用length
。例子:
for...in
is to be used when you want to loop over the properties of an object. But it works the same as a normalfor
loop: The loop variable contains the current "index", meaning the property of the object and not the value.To iterate over arrays, you should use a normal
for
loop.buttons
is not an array but aNodeList
(an array like structure).If iterate over
buttons
withfor...in
with:You will see that it output something like:
because
length
anditem
are two properties of an object of typeNodeList
. So if you'd naively usefor..in
, you would try to accessbuttons['length'].removeAttribute()
which will throw an error asbuttons['length']
is a function and not a DOM element.So the correct way is to use a normal
for
loop. But there is another issue:NodeList
s are live, meaning whenever you access e.g.length
, the list is updated (the elements are searched again). Therefore you should avoid unnecessary calls tolength
.Example:
for(var key in obj) { }
迭代对象中的所有元素,包括其原型的元素。因此,如果您正在使用它并且不知道任何扩展的
Object.prototype
,您应该始终测试obj.hasOwnProperty(key)
,如果此检查返回 false,则跳过该键。for(start; continuation;loop)
是一个 C 风格的循环:start
在循环之前执行,continuation
被测试并且仅循环当 true 时继续,loop
在每个循环后执行。for(var key in obj) { }
iterates over all elements in the object, including those of its prototypes.So if you are using it and cannot know nothing extended
Object.prototype
you should always testobj.hasOwnProperty(key)
and skip the key if this check returns false.for(start; continuation; loop)
is a C-style loop:start
is executed before the loop,continuation
is tested and the loop only continues while it's true,loop
is executed after every loop.不要使用
for..in
进行数组迭代。重要的是要了解 Javascript 数组用于访问索引的方括号语法 (
[]
) 实际上是从Object
... 的for..in 结构不像其他语言(php、python 等)中更传统的
for..each/in
那样工作。Javascript 的
for..in
旨在迭代对象的属性。生成每个属性的密钥。使用此键与对象
的括号语法相结合,您可以轻松访问所需的值。因为数组只是一个具有连续数字属性名称(索引)的对象,所以
for..in
以类似的方式工作,产生数字索引就像它产生上面的属性名称。for..in
结构的一个重要特征是它继续沿着原型链搜索可枚举属性。它还将迭代继承的可枚举属性。您需要验证当前属性是否直接存在于本地对象上,而不是通过hasOwnProperty()
附加到它的原型...(有关原型继承的更多信息)
在 Array 类型上使用
for..in
结构的问题在于,没有保证属性的生成顺序......一般来说,这是处理数组时非常重要的功能。另一个问题是它通常慢于标准
for
实施。底线
使用
for...in
来迭代数组就像使用螺丝刀的刀柄来钉钉子...为什么不直接使用锤子 (for< /代码>)?
Don't use
for..in
for Array iteration.It's important to understand that Javascript Array's square bracket syntax (
[]
) for accessing indicies is actually inherited from theObject
...The
for..in
structure does not work like a more traditionalfor..each/in
that would be found in other languages (php, python, etc...).Javascript's
for..in
is designed to iterate over the properties of an object. Producing the key of each property. Using this key combined with theObject
's bracket syntax, you can easily access the values you are after.And because the Array is simply an Object with sequential numeric property names (indexes) the
for..in
works in a similar way, producing the numeric indicies just as it produces the property names above.An important characteristic of the
for..in
structure is that it continues to search for enumerable properties up the prototype chain. It will also iterate inherited enumerable properties. It is up to you to verify that the current property exists directly on the local object and not the prototype it is attached to withhasOwnProperty()
...(More on Prototypal Inheritance)
The problem with using the
for..in
structure on the Array type is that there is no garauntee as to what order the properties are produced... and generally speaking that is a farily important feature in processing an array.Another problem is that it usually slower than a standard
for
implementation.Bottom Line
Using a
for...in
to iterate arrays is like using the butt of a screw driver to drive a nail... why wouldn't you just use a hammer (for
)?