310

ここで以前に回答された質問は、これが最速の方法であると言っていました:

//nl is a NodeList
var arr = Array.prototype.slice.call(nl);

私のブラウザでのベンチマークでは、これより 3 倍以上遅いことがわかりました。

var arr = [];
for(var i = 0, n; n = nl[i]; ++i) arr.push(n);

どちらも同じ出力を生成しますが、2 番目のバージョンが可能な限り最速の方法であるとは信じがたいと思います。

これは私のブラウザ (Chromium 6) の癖ですか? それとももっと速い方法がありますか?

編集:気になる人のために、私は以下に落ち着きました(これは私がテストしたすべてのブラウザーで最速のようです):

//nl is a NodeList
var l = []; // Will hold the array of Node's
for(var i = 0, ll = nl.length; i != ll; l.push(nl[i++]));

EDIT2:さらに速い方法を見つけました

// nl is the nodelist
var arr = [];
for(var i = nl.length; i--; arr.unshift(nl[i]));
4

14 に答える 14

227

2021 更新: nodeList.forEach() が標準になり、現在のすべてのブラウザーでサポートされます (デスクトップとモバイルの両方で約 95% )。

したがって、次のように簡単に実行できます。

document.querySelectorAll('img').forEach(highlight);

その他のケース

何らかの理由でそれを配列に変換するだけでなく、それを反復するだけでなく、これは完全に関連するユースケースです-[...destructuring]またはArray.fromES6以降を使用できます

let array1 = [...mySetOfElements];
// or
let array2 = Array.from(mySetOfElements);

これは、NodeList ではない他の配列のような構造でも機能します。

  • HTMLCollection例によって返されますdocument.getElementsByTagName
  • 長さプロパティとインデックス付き要素を持つオブジェクト
  • 反復可能なオブジェクト (MapやなどのオブジェクトSet)



古い2010年の回答

一部のブラウザーでは 2 番目の方が高速になる傾向がありますが、重要な点は、最初のブラウザーはクロスブラウザーではないため、それを使用する必要があるということです。たとえ時代が変わっても

@kangax ( IE 9 プレビュー)

Array.prototype.sliceは、特定のホスト オブジェクト (NodeList など) を配列に変換できるようになりました。これは、最近のブラウザーの大部分でかなり前から可能でした。

例:

Array.prototype.slice.call(document.childNodes);
于 2010-07-07T23:17:36.683 に答える
19

いくつかの最適化:

  • NodeList の長さを変数に保存する
  • 設定する前に、新しい配列の長さを明示的に設定します。
  • プッシュまたはシフト解除するのではなく、インデックスにアクセスします。

コード ( jsPerf ):

var arr = [];
for (var i = 0, ref = arr.length = nl.length; i < ref; i++) {
 arr[i] = nl[i];
}
于 2011-03-09T08:04:35.447 に答える
15

結果は完全にブラウザーに依存します。客観的な判断を下すには、いくつかのパフォーマンス テストを行う必要があります。いくつかの結果を次に示します。ここで実行できます。

クロム 6:

Firefox 3.6:

Firefox 4.0b2:

サファリ 5:

IE9 プラットフォーム プレビュー 3:

于 2010-07-07T23:31:58.523 に答える
15

最も高速でクロス ブラウザは

for(var i=-1,l=nl.length;++i!==l;arr[i]=nl[i]);

で比較したように

http://jsbin.com/oqeda/98/edit

*アイデアをくれた@CMSに感謝します!

クロム (Google Chrome に類似) ファイアフォックス オペラ

于 2013-02-28T19:43:48.847 に答える
7
NodeList.prototype.forEach = Array.prototype.forEach;

これで、 document.querySelectorAll('div').forEach(function()...) を実行できます

于 2014-12-25T17:52:33.417 に答える
5

より速く、より短く:

// nl is the nodelist
var a=[], l=nl.length>>>0;
for( ; l--; a[l]=nl[l] );
于 2013-01-22T14:11:40.677 に答える
3

これは、JSで使用する関数です。

function toArray(nl) {
    for(var a=[], l=nl.length; l--; a[l]=nl[l]);
    return a;
}
于 2013-03-08T03:21:33.660 に答える
3

同じことについて話しているこのブログ投稿をチェックしてください。私が収集したところによると、余分な時間はスコープ チェーンを上っていくことに関係している可能性があります。

于 2010-07-07T23:19:20.343 に答える