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


197

DOM NodeListを通常の配列に変換するためのこのきちんとしたショートカットに出くわしましたが、認める必要があります。それがどのように機能するのか完全には理解していません。

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

それは空の配列で始まるので[]、その後sliceの結果を変換するために使用されるcallええ新しい配列に?

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


5
Array.prototype.slice.call(document.querySelectorAll('a'));あなたが書いたコードのチャンクを書くための適切な方法です。
vdegenne、2015

4
ところで、最新の(そして直感的に理解できる)ES6の方法は Array.fromです。したがって、たとえばこれは同じことを行います。Array.from(document.querySelectorAll( 'a'));
rugk

回答:


158

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

編集:

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

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


59
これも意味的にはと同等ですがArray.prototype.slice.call(...)、実際には配列オブジェクト([])をインスタンス化して、そのプロトタイプのスライスメソッドにアクセスするだけです。それは無駄なインスタンス化です。Array.prototype.slice.call(...)カウントする場合はJSにいくつかの文字を追加しますが、代わりに言うのはよりきれいです
Ben Zotto

これはIE 8以下ではArrayオブジェクトでのみ機能するため、NodeListsのクローンを作成できないことに注意してください
Livingston Samuel

5
@quixoto []Array他のものに上書きされる可能性があるため、より信頼性が高くなります。を再利用する必要がある場合はArray#slice、キャッシュすることをお勧めします。
Mathias Bynens、2011年

2
場合、誰がこの質問をチェックアウト、IE8でこれを行う方法を探しているstackoverflow.com/questions/3199588/...
リアムNewmarch

1
私は実際にこのパターンがbackbone.jsソースコードに表示されるのを見ました: var array = []; var push = array.push; var slice = array.slice; var splice = array.splice;彼は@MathiasBynensが言及する安全問題のためにこれを行いますか?
オーウェンスマーティン2014

125

JavaScriptでは、オブジェクトのメソッドを実行時に別のオブジェクトにバインドできます。要するに、JavaScriptはオブジェクトが別のオブジェクトのメソッドを「借りる」ことを可能にします:

object1 = {
    name: 'Frank',
    greet() {
        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が配列のスライスメソッドを借用していると言えます。.slice()結果として別の配列を返します。これは、使用できる「変換された」配列になります。


javascriptオブジェクトの関数のconceptの抽象的な概念説明。これで、別名のcall機能に適用できます。Array.prototype[].prototype
スーラバ

29

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


19

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

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

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

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

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

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


15

どのようにdocument.querySelectorAll('a')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バインドすることにより、関数が呼び出されます。すなわち] を含む引数thisthisArgdocument.querySelectorstart0

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

  • startsとして変数に割り当てられます0
  • 以来endundefinedthis.length中に保存されますe
  • 空の配列は変数に格納されます a
  • 上記の設定を行った後、次の反復が行われます

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

PSシナリオをよりよく理解するために、コンテキストに必要ないくつかの手順は、呼び出しスライスの元のアルゴリズムから無視されています


1
ステップバイステップの説明でとても素敵です。驚くばかり!ありがとうございました:)
kittu 2017

1
いい説明。
NaveenDA 2017

7
[].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>

4

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.