web-dev-qa-db-ja.com

JavaScriptの[] .slice.callの説明?

DOM NodeListを通常の配列に変換するためのこの便利なショートカットを見つけましたが、それがどのように機能するか完全には理解していません。

[].slice.call(document.querySelectorAll('a'), 0)

空の配列[]で始まり、sliceを使用してcallの結果を新しい配列に変換しますか?

私が理解できないビットはcallです。 document.querySelectorAll('a')をNodeListから通常の配列にどのように変換しますか?

178
Yansky

ここで起こっているのは、slice()を使用してNodeListの関数であるかのようにcall()を呼び出すことです。この場合のslice()は、空の配列を作成し、実行中のオブジェクト(元は配列、現在はNodeList)を反復処理し、そのオブジェクトの要素を空の配列に追加し続けます作成され、最終的に返されます。 これに関する記事 です。

編集:

空の配列[]で始まり、スライスを使用して呼び出しの結果を新しい配列に変換します。

そうではありません。 [].sliceは、関数オブジェクトを返します。関数オブジェクトには、call()の最初のパラメーターをthisに割り当てる関数を呼び出す関数call()があります。言い換えると、配列からではなく、パラメータ(document.querySelectorAll('a')によって返されるNodeList)から呼び出されていると関数に思わせます。

144
Max Shawabkeh

Javascriptでは、オブジェクトのメソッドを実行時に別のオブジェクトにバインドできます。つまり、javascriptを使用すると、オブジェクトは別のオブジェクトのメソッドを「借りる」ことができます。

object1 = {
    name:'frank',
    greet:function(){
        alert('hello '+this.name)
    }
};

object2 = {
    name:'andy'
};

// Note that object2 has no greet method.
// But we may "borrow" from object1:

object1.greet.call(object2); // will show an alert with 'hello andy'

関数オブジェクトのcallおよびapplyメソッド(javascript関数の場合もオブジェクトです)を使用すると、これを行うことができます。したがって、コードでは、Nodelistは配列のスライスメソッドを借用していると言えます。変換とは、スライスが結果として別の配列を返すという事実です。

110
slebetman

sliceからArray関数を取得します。次に、その関数を呼び出しますが、実際の配列の代わりにthisオブジェクトとしてdocument.querySelectorAllの結果を使用します。

26
Brian Campbell

これは、配列のようなオブジェクトを実際の配列に変換する手法です。

これらのオブジェクトの一部は次のとおりです。

  • arguments 関数内
  • NodeList (コンテンツは取得後に変更される可能性があることに注意してください!配列に変換することは、それらをフリーズする方法です)
  • jQueryコレクション、別名jQueryオブジェクト(一部のドキュメント: APItypelearn

これには多くの目的があります。たとえば、オブジェクトは参照によって渡され、配列は値によって渡されます。

また、最初の引数0は省略できることに注意してください ここでの詳細な説明

また、完全を期すために、 jQuery.makeArray() もあります。

19
Gras Double

document.querySelectorAll('a')NodeListから通常の配列にどのように変換しますか?

これは私たちが持っているコードです、

[].slice.call(document.querySelectorAll('a'), 0)

まず解体しましょう、

  []    // Array object
.slice // Accessing the function 'slice' present in the prototype of Array
.call // Accessing the function 'call' present in the prototype of function object(slice)
(document.querySelectorAll('a'),0) 
    // 'call' can have arguments like, (thisArg, arg1,arg2...n). 
   // So here we are passing the 'thisArg' as an array like object,
  // that is a 'nodeList'. It will be served as 'this' object inside of slice function.
 // And finally setting 'start' argument of slice as '0' and leaving the 'end' 
// argument as 'undefined'

ステップ:1 call関数の実行

  • call以外のthisArg内では、残りの引数が引数リストに追加されます。
  • これで、関数sliceは、そのthis値をthisArg(オブジェクトのような配列はdocument.querySelectorから取得)として引数リストにバインドすることによって呼び出されます。つまり、0を含む引数start

ステップ:2 slice内で呼び出されるcall関数の実行

  • startは変数s0として割り当てられます
  • endundefinedであるため、this.lengtheに格納されます
  • 空の配列は変数aに格納されます
  • 上記の設定を行った後、次の反復が行われます

    while(s < e) {
      a.Push(this[s]);
      s++;
    }
    
  • 埋められた配列aが結果として返されます。

P.Sシナリオをよりよく理解するために、コンテキストに必要ないくつかの手順は、元のアルゴリズム call および slice から無視されています。

[].slice.call(document.querySelectorAll('.slide'));

1. The querySelectorAll() method returns all elements in the document that matches a specified selector(s). 

2. The call() method calls a function with a given this value and arguments provided individually.

3. The slice() method returns the selected elements in an array, as a new array object.

  so this line return the array of [object HTMLDivElement]. Here is the six div with classname "slide" so array length will be 6.

<div class="slideshow">

  <div class="slide">
    first slider1
  </div>
  <div class="slide">
    first slider2
  </div>
  <div class="slide">
    first slider3
  </div>
  <div class="slide">
    first slider4
  </div>
  <div class="slide">
    first slider5
  </div>
  <div class="slide">
    first slider6
  </div>

</div>

<script type="text/javascript">

  var arraylist = [].slice.call(document.querySelectorAll('.slide'));

  alert(arraylist);

</script>
5
Ankit Parmar

ES6から:Array.from(element.children)またはArray.from({length:5})で配列を作成するだけです

3
Мони