4

本 Javascript: the definitive Guide Sixth Edition by David Flanagan の 147 ページで、著者は for..in ループを使用して配列を反復処理するときの注意事項について説明しています。以下は引用です (太字は私のものです)。

...このため、不要なプロパティを除外する追加のテストを含めない限り、配列で for/in ループを使用しないでください。 次のいずれかのテストを使用できます

for(var i in a) {
   if (!a.hasOwnProperty(i)) continue; // Skip inherited properties
   // loop body here
}

for(var i in a) {
   // Skip i if it is not a non-negative integer
   if (String(Math.floor(Math.abs(Number(i)))) !== i) continue;
}

これで、最初のコード スニペットが明確になりました。継承されたプロパティはスキップされます。

ただし、2 番目のコード スニペットはまったくわかりません。

私の理解では、2 番目のコード スニペットは配列の数値以外のプロパティをスキップします (それが独自のプロパティであるかどうかにかかわらず (最初のコード スニペットとは異なります))。

しかし、その場合は、次のような単純化されたテストを使用できませんでした:

if (Number(i) != i) continue;

では、著者はなぜこのような複雑な表現を使用しているのでしょうか。

ここで何か不足していますか?

4

1 に答える 1

2

いいえ、失敗する例を次に示します。

浮動小数点数:

var a = [1, 2, 3];
a['1.5'] = 'busted';
for(var i in a) {
    if (Number(i) != i) continue;
    document.getElementById('output1').textContent += i + '\n';
}
for(var i in a) {
    if (String(Math.floor(Math.abs(Number(i)))) !== i) continue;
    document.getElementById('output2').textContent += i + '\n';
}
<h3>Number(i) != i</h3>
<pre id="output1"></pre>
<h3>String(Math.floor(Math.abs(Number(i)))) !== i</h3>
<pre id="output2"></pre>

負の数:

var a = [1, 2, 3];
a['-5'] = 'busted';
for(var i in a) {
    if (Number(i) != i) continue;
    document.getElementById('output1').textContent += i + '\n';
}
for(var i in a) {
    if (String(Math.floor(Math.abs(Number(i)))) !== i) continue;
    document.getElementById('output2').textContent += i + '\n';
}
<h3>Number(i) != i</h3>
<pre id="output1"></pre>
<h3>String(Math.floor(Math.abs(Number(i)))) !== i</h3>
<pre id="output2"></pre>

これは、Math.absandMath.floor呼び出しが防御しているものです。

ところで、配列インデックスに for in ループを使用する利点はありません。インデックスベースのループを使用することをお勧めします。

于 2015-11-29T08:09:39.887 に答える