web-dev-qa-db-ja.com

JavaScript NodeListを配列に変換する最速の方法は?

ここで以前に回答された質問は、これが最速の方法であると述べました。

//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]));
234
jairajs89

2番目のブラウザは一部のブラウザでは高速になる傾向がありますが、主なポイントは、最初のブラウザはクロスブラウザではないため、使用する必要があるということです。タイムズゼアアーアーチャンギン

@ kangaxIE 9プレビュー

Array.prototype.sliceは、特定のHostオブジェクト(NodeListなど)を配列に変換できるようになりました。これは、現代のブラウザーの大部分が、ながら。

例:

Array.prototype.slice.call(document.childNodes);
187
gblazex

ES6では、NodeListから配列を作成する簡単な方法があります: Array.from() 関数。

// nl is a NodeList
let myArray = Array.from(nl)
193
webdif

ES6スプレッド演算子 を使用してそれを行う新しいクールな方法を次に示します。

let arr = [...nl];
93

いくつかの最適化:

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

コード( jsPerf ):

var arr = [];
for (var i = 0, ref = arr.length = nl.length; i < ref; i++) {
 arr[i] = nl[i];
}
19
Thai

結果はブラウザに完全に依存するため、客観的な判定を行うには、パフォーマンステストを行う必要があります。ここに結果を示します。実行できるのは here

Chrome 6:

Firefox 3.6:

Firefox 4.0b2:

Safari 5:

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

15
CMS

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

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

私が比較したように

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

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

Chromium (Similar to Google Chrome)FirefoxOpera

14
Felipe Buccioni
NodeList.prototype.forEach = Array.prototype.forEach;

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

7
John Williams

より速く、より短く:

// nl is the nodelist
var a=[], l=nl.length>>>0;
for( ; l--; a[l]=nl[l] );
5
anonymous

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

function toArray(nl) {
    for(var a=[], l=nl.length; l--; a[l]=nl[l]);
    return a;
}
3
Web_Designer

このブログ投稿をチェックしてください here 同じことについて語っています。私が収集したものから見ると、余計な時間はスコープチェーンを上るのに関係しているかもしれません。

3
Vivin Paliath

ES6では、次のいずれかを使用できます。

  • Array.from

    let array = Array.from(nodelist)

  • スプレッド演算子

    let array = [...nodelist]

3
Isabella

以下は、この投稿の日付時点で更新されたチャートです(「不明なプラットフォーム」チャートはInternet Explorer 11.15.16299.0です)。

Safari 11.1.2Firefox 61.0Chrome 68.0.3440.75Internet Explorer 11.15.16299.0

これらの結果から、preallocate 1メソッドが最も安全なクロスブラウザベットであると思われます。

1
TomSlick

nodeList = document.querySelectorAll("div")と仮定すると、これはnodelistを配列に変換する簡潔な形式です。

var nodeArray = [].slice.call(nodeList);

私はそれを使用して参照してください ここ

0
Udo E.