2

for...inJavascriptでステートメントを試しました。

これはエラーを発生させません:

var images = document.getElementsByTagName('img');

for(x in images){
    document.write(images[x]) + " ");
}

ただし、これは本来あるべきことを実行しますが、FFエラーコンソールでエラーが発生します。

for(x in images){
    images[x].style.visibility="visible";
}

これは私に何が起こっているのかについて非常に興味をそそられました。

これを行う:

for(x in images){
    document.write(x);
}

...私にこれをくれた:

01234567891011121314151617lengthitemnamedItem

最後に何がありますか?最後のxの値は画像に対応しないため、これによりdocument.images/document.getElementsByTagName('img')配列をステートメントで使用するのに適さないと思いますか?for...inたぶんforループの方がいいですか?

4

3 に答える 3

5

for ... inループのある配列を反復処理しないでください。インデックスを使用します。

for (var i = 0; i < arr.length; ++i) {
  // images[i] ...
}

for ... in構成は間違っていません、それはあなたがやりたいことではありません。これは、オブジェクトのすべてのプロパティを反復処理する場合に使用します。配列はオブジェクトであり、意味的に興味深いインデックス付き要素以外にも他のプロパティがあります。

(実際には、そこから返されるのは実際には配列でgetElementsByTagNameはありませ。これはノードリストです。ただし、配列のように扱うことができ、通常は問題なく機能します。同じ基本的な注意事項がfor ... inどのような場合にも当てはまります。)

于 2010-09-06T16:35:45.253 に答える
1

for..in does not loop through the indexes of an array, it loops through the enumerable property names of an object. It happens that the only enumerable properties array instances have, by default, are array indexes, and so it mostly works to think it does array indexes in limited situations. But that's not what for..in does, and misunderstanding this will bite you. :-) It breaks as soon as you add any further properties to the array (a perfectly valid thing to do) or any library you're using decides to extend the array prototype (also a valid thing to do).

In any case, what you get back from document.getElementsByTagName isn't an array. It's a NodeList. Your best bet for iterating through NodeLists is to use an explicit index a'la Pointy's answer -- e.g., a straight counting loop:

var i;
for (i = 0; i < list.length; ++i) {
    // ... do your thing ...
}

Somewhat off-topic because it doesn't relate to your NodeList, but: When you are actually working with a real array, because arrays in JavaScript are sparse, there is applicability for for..in, you just have to be clear about what you're doing (looping through property names, not indexes). You might want to loop only as many times as the array has actual entries, rather than looping through all the indexes in the gaps in the sparse array. Here's how you do that:

var a, name;
a = [];
a[0] = "zero";
a[10000] = "ten thousand";
for (name in a) {
    // Only process this property name if it's a property of the
    // instance itself (not its prototype), and if the name survives
    // transition to and from a string unchanged -- e.g., it's numeric
    if (a.hasOwnProperty(name) && parseInt(name) == name) {
        alert(a[name]);
    }
}

The above only alerts twice, "zero" and "ten thousand"; whereas a straight counting loop without the checks would alert 10,001 times (mostly saying "undefined" because it's looping through the gap).

于 2010-09-06T16:43:27.783 に答える
0

コンストラクトの問題はfor ... in、プロトタイプのすべてが列挙に含まれることです。

出力に表示されているのは、基本的に、配列オブジェクトであるのすべての属性です。imagesだからあなたは得る

  1. 配列内のすべての要素、つまり出力に表示される数値。
  2. 配列で使用可能なすべてのプロパティ。これがlength、たとえば出力に表示される理由です。

関数にはスタイル属性がないため、コードは2番のために壊れます

したがって、はい、Pointyが示すように、JavaScriptで配列の要素を反復処理する正しい方法は、forループを使用することです。

于 2010-09-06T16:50:36.737 に答える