コードのスニペットを見ていましたが、空の配列にforEachが適用されたノードリストで関数を呼び出す複数の要素が見つかりました。
たとえば、次のようなものがあります。
[].forEach.call( document.querySelectorAll('a'), function(el) {
// whatever with the current node
});
しかし、私はそれがどのように機能するのか理解できません。 forEachの前にある空の配列の動作とcall
の動作を誰にも説明できますか?
querySelectorAll
メソッド はNodeList
を返します。これは配列に似ていますが、配列ではありません。したがって、forEach
メソッドはありません(配列オブジェクトはArray.prototype
を介して継承します)。
NodeList
は配列に似ているため、配列メソッドは実際に動作します。したがって、[].forEach.call
を使用することで、NodeList
のコンテキストでArray.prototype.forEach
メソッドを呼び出します。単にyourNodeList.forEach(/*...*/)
を実行できたかのように。
空の配列リテラルは、展開されたバージョンへのショートカットにすぎないことに注意してください。
Array.prototype.forEach.call(/*...*/);
他の回答はこのコードを非常によく説明しているので、提案を追加します。
これは、簡単かつ明確にするためにリファクタリングする必要があるコードの良い例です。これを行うたびに[].forEach.call()
またはArray.prototype.forEach.call()
を使用する代わりに、それから単純な関数を作成します。
function forEach( list, callback ) {
Array.prototype.forEach.call( list, callback );
}
より複雑で曖昧なコードの代わりに、この関数を呼び出すことができます:
forEach( document.querySelectorAll('a'), function( el ) {
// whatever with the current node
});
を使用してより良く書くことができます
Array.prototype.forEach.call( document.querySelectorAll('a'), function(el) {
});
document.querySelectorAll('a')
は、配列に似たオブジェクトを返しますが、Array
型を継承しません。したがって、document.querySelectorAll('a')
によって返される値としてコンテキストを使用して、Array.prototype
オブジェクトからforEach
メソッドを呼び出します。
私がいつも使っている、ただの汚い解決策です。良いプラクティスと同じように、プロトタイプには触れません。もちろん、これを改善する方法はたくさんありますが、アイデアは得られます。
const forEach = (array, callback) => {
if (!array || !array.length || !callback) return
for (var i = 0; i < array.length; i++) {
callback(array[i], i);
}
}
forEach(document.querySelectorAll('.a-class'), (item, index) => {
console.log(`Item: ${item}, index: ${index}`);
});
1行追加するだけです:
NodeList.prototype.forEach = HTMLCollection.prototype.forEach = Array.prototype.forEach;
そして出来上がり!
document.querySelectorAll('a').forEach(function(el) {
// whatever with the current node
});
楽しい :-)
警告: NodeListはグローバルクラスです。パブリックライブラリを作成する場合は、この推奨事項を使用しないでください。ただし、Webサイトまたはnode.jsアプリで作業する場合、自己効力感を高めるための非常に便利な方法です。
[]
は常に新しい配列を返します。new Array()
と同等ですが、Array
はユーザーによって上書きされる可能性がありますが、[]
は上書きできないため、配列を返すことが保証されます。したがって、これはArray
のプロトタイプを取得する安全な方法であり、次に説明したように、call
を使用してarraylike nodelist(this)で関数を実行します。
この値と引数を個別に指定して関数を呼び出します。 mdn
この古い質問について更新したい:
最新のブラウザで[].foreach.call()
を使用して要素をループする理由はほとんど終わりました。 document.querySelectorAll("a").foreach()
を直接使用できます。
NodeListオブジェクトはノードのコレクションであり、通常はNode.childNodesなどのプロパティとdocument.querySelectorAll()などのメソッドによって返されます。
NodeListは配列ではありませんが、forEach()で繰り返し処理することができます。 Array.from()を使用して実際の配列に変換することもできます。
ただし、一部の古いブラウザーはNodeList.forEach()もArray.from()も実装していません。これは、Array.prototype.forEach()を使用して回避できます。このドキュメントの例を参照してください。
Norguard 説明[].forEach.call()
が行うこと James Allardiceなぜそれを行うのか:querySelectorAllはforEachメソッドを持たないNodeList
を返すため...
Chrome 51 +、Firefox 50 +、Opera 38、Safari 10などの最新のブラウザを使用している場合を除きます。
そうでない場合は、 Polyfill を追加できます:
if (window.NodeList && !NodeList.prototype.forEach) {
NodeList.prototype.forEach = function (callback, thisArg) {
thisArg = thisArg || window;
for (var i = 0; i < this.length; i++) {
callback.call(thisArg, this[i], i, this);
}
};
}