回答:
[]
配列です。
この配列はまったく使用されません。
配列を使用すると、のような配列プロトタイプにアクセスできるため、ページに配置されます.forEach
。
これはタイピングよりも速いです Array.prototype.forEach.call(...);
次に、forEach
関数を入力として受け取る関数です...
[1,2,3].forEach(function (num) { console.log(num); });
...そしてthis
(this
配列のように、があり、のようにlength
その部分にアクセスできるという点で)各要素に対して、次のthis[1]
3つを渡します。
2
)最後に、.call
関数が持っているプロトタイプです(他の関数で呼び出される関数です)。
.call
最初の引数を取りthis
、通常の関数内をcall
最初の引数として渡したものに置き換えます(undefined
または毎日のJSでnull
使用するwindow
か、「strict-mode」の場合は渡したものになります)。残りの引数は元の関数に渡されます。
[1, 2, 3].forEach.call(["a", "b", "c"], function (item, i, arr) {
console.log(i + ": " + item);
});
// 0: "a"
// 1: "b"
// 2: "c"
したがって、forEach
関数を呼び出す簡単な方法を作成this
し、空の配列からすべての<a>
タグのリストに変更します。それぞれ<a>
の順序で、提供された関数を呼び出します。
以下は、関数型プログラミングの試みを破棄し、手動のインラインループに固執することを提案する記事へのリンクです。このソリューションはハックのようで見苦しいためです。
私はしばらくは言うだろう.forEach
、その対応よりも小さいと便利です.map(transformer)
、.filter(predicate)
、.reduce(combiner, initialValue)
のいずれかへのアクセス持ちながら、あなたが本当にやりたいすべてが外の世界(ない配列)を変更する場合、それはまだの目的を果たし、n回arr[i]
かをi
。
モットは明らかに才能があり知識豊富な男なので、どのようにして格差に対処しますか。また、自分がやっていること/どこに向かっているのか(たまには...そして他の...)時それは頭からの学習です)?
答えは実際には非常に単純で、ボブおじさんとクロックフォード卿はどちらも見落としのためにどちらも直面するでしょう。
片付けてください。
function toArray (arrLike) { // or asArray(), or array(), or *whatever*
return [].slice.call(arrLike);
}
var checked = toArray(checkboxes).filter(isChecked);
checked.forEach(listValues);
さて、あなたが自分でこれを行う必要があるかどうか疑問に思っているなら、答えはおそらくノーかもしれません...
この正確なことは...最近の高次機能を備えたevery(?)ライブラリによって行われます...
lodash、アンダースコア、またはjQueryを使用している場合、それらはすべて、要素のセットを取得し、アクションをn回実行する方法を持っています。
もしあなたがそのようなものを使っていないなら、ぜひ、あなた自身のものを書いてください。
lib.array = (arrLike, start, end) => [].slice.call(arrLike, start, end);
lib.extend = function (subject) {
var others = lib.array(arguments, 1);
return others.reduce(appendKeys, subject);
};
slice( )
/ array( )
/ etcヘルパーメソッドは、配列を使用するのと同じようにリストを使用したい人のために便利なだけでなく、比較的近いES6 +ブラウザーで操作できる贅沢な人のためにも役立ちます将来、または今日のバベルの「トランスパイル」では、言語機能が組み込まれているため、このタイプのことは不要になります。
function countArgs (...allArgs) {
return allArgs.length;
}
function logArgs (...allArgs) {
return allArgs.forEach(arg => console.log(arg));
}
function extend (subject, ...others) { /* return ... */ }
var nodeArray = [ ...nodeList1, ...nodeList2 ];
超クリーンでとても便利です。
見上げて休息やスプレッド演算子を。BabelJSサイトで試してください。テックスタックが適切な場合は、バベルとビルドステップを使用して本番環境で使用します。
非配列から配列への変換を使用できないようにする正当な理由はありません... ... どこでも、同じ醜い行を貼り付けるだけでコードを混乱させないでください。
.call
の値は変更されthis
ます。これがcall
、forEachで使用している理由です。forEachがそのように見える場合、言うことforEach (fn) { var i = 0; var len = this.length; for (; i < length; i += 1) { fn( this[i], i, this ); }
によって変更this
するforEach.call( newArrLike )
ことは、その新しいオブジェクトをとして使用することを意味しますthis
。
.call
は、this
渡されたものの内部の値を変更せず、forEachの内部の値を変更します。呼び出したい関数に渡されない理由がわからない場合は、JavaScriptの動作を調べてください。補足として、ここ(およびmap / filter / reduce)のみに適用可能です。2番目の引数がにあり、関数の内部を設定するか、または単にを使用します。forEach
.call
this
this
forEach
this
forEach
this
arr.forEach(fn, thisInFn)
[].forEach.call(arrLike, fn, thisInFn);
.bind
arr.forEach(fn.bind(thisInFn));
[]
配列として存在するだけなので.call
、.forEach
メソッドを使用して、this
作業を行いたいセットに変更できます。.call
これは次のようになります。function (thisArg, a, b, c) { var method = this; method(a, b, c); }
ただし、内部に設定する内部ブラックマジックがthis
あり、method
渡したものと同じですthisArg
。
このquerySelectorAll
メソッドはを返しますNodeList
。これは配列に似ていますが、配列ではありません。したがって、forEach
(配列オブジェクトがを介して継承するArray.prototype
)メソッドはありません。
NodeList
は配列に似ているので、配列メソッドは実際に配列で機能します。そのため、を使用して、のコンテキストでメソッドを[].forEach.call
呼び出すことができます。Array.prototype.forEach
NodeList
yourNodeList.forEach(/*...*/)
空の配列リテラルは拡張バージョンへのショートカットにすぎないことに注意してください。
Array.prototype.forEach.call(/*...*/);
[].forEach.call(['a','b'], cb)
し['a','b'].forEach(cb)
て日常のアプリケーションでover を使用しforEach
ても、独自のプロトタイプを持たない配列のような構造を反復しようとするだけの利点はありませんか?あれは正しいですか?
[].forEach()
:)
var section = document.querySelectorAll(".section"); section.forEach((item)=>{ console.log(item.offsetTop) })
うまくいく
forEach
アレイ上ではなく、のNodeListオブジェクト)
他の回答はこのコードを非常によく説明しているので、提案を追加します。
これは、簡潔さと明確さのためにリファクタリングする必要があるコードの良い例です。を使用する代わりに、[].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
});
この古い質問を更新したい:
[].foreach.call()
最近のブラウザで要素をループするために使用する理由はほとんどありません。document.querySelectorAll("a").foreach()
直接使用できます。
NodeListオブジェクトはノードのコレクションであり、通常はNode.childNodesなどのプロパティやdocument.querySelectorAll()などのメソッドによって返されます。
NodeListは配列ではありませんが、forEach()を使用して反復できます。Array.from()を使用して実際の配列に変換することもできます。
ただし、一部の古いブラウザはNodeList.forEach()やArray.from()を実装していません。これは、Array.prototype.forEach()を使用して回避できます。このドキュメントの例を参照してください。
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アプリで作業するときに自己効力感を高めるための非常に便利な方法です。
私がいつも使用している、素早くて汚いソリューションです。プロトタイプには触れないようにします。もちろん、これを改善する方法はたくさんありますが、アイデアは思い付きます。
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}`);
});
[]
常に新しい配列を返します。これは同等ですnew Array()
がArray
、ユーザーが上書きできるのに上書きできないため、配列を返すことが保証されています[]
。したがって、これはのプロトタイプを取得する安全な方法でありArray
、次に説明call
するように、配列のようなノードリスト(this)で関数を実行するために使用されます。
指定されたthis値と個別に提供された引数を使用して関数を呼び出します。mdn
[]
、実際に意志は常に配列を返す、しばらくはwindow.Array
そうあまりにもすることができ、(すべての古いブラウザでは)何も上書きできるwindow.Array.prototype.forEach
もので上書きします。どちらの場合でも、ゲッター/セッターまたはオブジェクトのシーリング/フリーズ(フリーズによって拡張性の問題が発生する)をサポートしていないブラウザーでは、安全性は保証されません。
prototype
またはメソッドを上書きする可能性に関する追加情報を追加するには、回答を自由に編集してください:forEach
。
Norguardは、WHAT [].forEach.call()
とJames Allardiceが なぜそれを行うのかを説明しました。querySelectorAllがNodeList
forEachメソッドを持たないを返すためです...
Chrome 51以降、Firefox 50以降、Opera 38、Safari 10などの最新のブラウザを使用している場合を除きます。
そうでない場合は、ポリフィルを追加できます。
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);
}
};
}
このページにはたくさんの良い情報がありますが(回答 + 回答 + コメントを参照)、最近OPと同じ質問があり、全体像を把握するには少し掘り下げました。だから、ここに短いバージョンがあります:
目標はArray
、配列のようなメソッドを使用することですNodeList
それらのメソッド自体を持たないすることです。
古いパターンはFunction.call()
、を介してArrayのメソッドを選択し、タイプするのがより短かったためでは[]
なく、配列リテラル()を使用していましたArray.prototype
。
[].forEach.call(document.querySelectorAll('a'), a => {})
新しいパターン(ポストECMAScript 2015)は以下を使用することArray.from()
です:
Array.from(document.querySelectorAll('a')).forEach(a => {})