2012-06-07 10 views
9

私はどこかにこのスクリプトを見て、それはすべての単一のチェックボックスをチェックします:は "[] .forEach"

[].forEach.call(document.querySelectorAll('input[type="checkbox"]'),function(el){ 
     el.checked=true; 
    } 
);​ 

私はforEachを使用する方法を知っている:今

[0,1,2].forEach(function(num){ 
    console.log(num); 
}); 

//0 
//1 
//2 

しかし、それは[].forEachで、内部には何もありません。では、なぜそれはまだ動作しますか?なぜ私はこれを代わりにすることができないのですか?

document.querySelectorAll('input[type="checkbox"]').forEach(function(el){ 
     el.checked=true; 
    } 
);​ 
+0

できます。最初は反射を通して同じになってしまいます。 'call'と' apply'をチェックしてください。 – entonio

+2

この[]] .forEach.call(nodeList、fn) 'テクニック**はIE8では動作しません**ので、一般的な状況では使用できません。 –

+1

'querySelectorAll'の結果に使用する方法を技術的に*追加することはできますが、それは危険を伴う道です。 'NodeList.prototype.forEach = HTMLCollection.prototype.forEach = Array.prototype.forEach; –

答えて

10

JavaScriptには、ファーストクラスの機能があります。つまり、オブジェクトのように扱われ、独自のプロパティとメソッドを持つことができます。組み込まれたFunction.callメソッドは、関数の最初の引数としてthisパラメータをとり、残りの引数は関数自体に渡されます。配列[]は、(あまり簡潔であまり使用されない)Array.prototype.forEachメソッドにアクセスする手段を除いて、使用されません。

基本的に配列ではないもの(この場合はNodeList)に使用するためのArray.forEachの再バインドです。 NodeList sがforEach方法を提供している場合、それは以下と等価になり、あなたは、このようにそれを読むことがあります。もう少し深さそう

document.querySelectorAll('input[type="checkbox"]').forEach(function(el) { 
    el.checked = true; 
});​ 

、。 callは、異なるコンテキストを持つ関数を実行します。 forEachはコンテキストを反復し、引数として渡された関数を呼び出します。したがって、someFunc.call(thisArg, otherArg)は、thisArg.someFunc(otherArg)のように、thisArgのコンテキストにあるかのように実行されます。ここでは最も簡単な例です:

function callMe(something) { 
    return something + this; 
} 

callMe('Hello'); // Hellonull or Hello[object Window] or something 
callMe.call({}, 'World'); // World[object Object] 

apply()は同じように動作しますが、2番目の引数として、引数の配列を渡します。

+0

何を待ちますか?だから 'Array'の代わりに' NodeList'ですか? 'NodeList' *が' Array'ではないのですか? –

+2

いいえ、NodeListは配列ではありません。しかし基本的には、配列と同様に動作します。これは数値インデックスと 'length'プロパティを持ちます。これは標準の 'Array'メソッドを継承しません。しかし、 'メソッド'が索引付けと 'length'だけを必要とするならば、これはうまくいくでしょう。このため、この特定のコードスニペットが有効です。 –

+0

@TikhonJelvis - それは 'Array'が持たなければならないメソッドを持たない' Array'です。そうですか。 –

3

.callに注目してください。 にはdocument.querySelectorAllforEachの結果が適用されるため、ドットの左側の(空の)配列ではなく、その結果を反復処理します。

4

[]を使用して、forEach機能を使用しています。機能があれば、.callを使用して、そのメソッドをdocument.querySelectorAll('input[type="checkbox"]')のように呼び出します。

これは、Arrayの結果ではありませんが、同じように動作するので、便利です。標準のArrayメソッドを再利用できます。

.callを使用すると、最初の引数はthisの値として使用されます。つまり、この特定のスニペットでは、がソースforEachの内部で発生するたびに、document.querySelectorAll('input[type="checkbox"]')に設定されます。

querySelectorAllArrayオブジェクトを返していないので、forEach方法を持っていないので、あなただけの直接document.querySelectorAll('input[type="checkbox"]').forEach(...を呼び出すことはできません。.callというものは、forEachと呼んでこれを回避する方法です。実際に返されるのはNodeListのメソッドでした。