Javascript [] .slice.call açıklaması?


197

Bir DOM NodeList normal bir dizi dönüştürmek için bu temiz kısayol tökezledi, ama itiraf etmeliyim, tamamen nasıl çalıştığını anlamıyorum:

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

Yani boş bir dizi ile başlar [], sonra slicesonucu callyeni bir diziye dönüştürmek için kullanılır evet?

Anlamıyorum biraz call. Bu document.querySelectorAll('a'), bir NodeList'ten normal bir diziye nasıl dönüşür?


5
Array.prototype.slice.call(document.querySelectorAll('a'));yazdığınız kod yığınını yazmanın uygun bir yoludur.
vdegenne

4
BTW, modern (ve sezgisel olarak anlaşılabilir) ES6 için aynı yöntemdir Array.from. Yani, örneğin bu aynısını yapar: Array.from (document.querySelectorAll ('a'));
rugk

Yanıtlar:


158

Burada olan şey, slice()sanki bir NodeListkullanma işleviymiş gibi çağırmanızdır call(). Ne slice()bu durumda does üzerinde çalıştığı nesneye (şimdi bir başlangıçta bir dizi aracılığıyla sonra, iterate boş bir dizi oluşturmaktır NodeList) ve en sonunda döndürülür oluşturulduktan boş diziye, bu nesnenin eleman eklenmesi tutun. İşte bununla ilgili bir makale .

DÜZENLE:

Yani boş bir dizi [] ile başlıyor, sonra dilim çağrının sonucunu yeni bir diziye dönüştürmek için kullanılıyor evet?

Bu doğru değil. [].slicebir işlev nesnesi döndürür. Bir işlev nesnesinin, to call()parametresinin ilk parametresini atayan işlevi çağıran bir işlevi vardır ; diğer bir deyişle, işlevin bir dizi yerine parametreden ( döndürülen ) çağrıldığını düşündürür .call()thisNodeListdocument.querySelectorAll('a')


59
Her ne kadar bu anlamsal olarak söylemeye eşdeğer olsa da Array.prototype.slice.call(...), aslında []sadece bir prototipi dilim yöntemine erişmek için bir dizi nesnesini ( ) başlatır . Bu boşa giden bir örnek. Array.prototype.slice.call(...)Eğer sayıyorsanız
JS'nize

IE 8 ve aşağıda sadece Dizi nesneler üzerinde bu eserler, sen klon mümkün olmayacaktır edeceğiz böylece Not NodeListler
Livingston Samuel

5
@ quixoto []daha güvenilirdir çünkü Arraybaşka bir şeye yazılabilir. Yeniden kullanmanız gerekiyorsa Array#slice, önbelleğe almak iyi bir fikirdir.
Mathias Bynens

2
Başka birinin IE8'de bunu yapmanın bir yolunu araması durumunda, bu soruya göz
Liam Newmarch

1
Aslında bu kalıbın backbone.js kaynak kodunda göründüğünü gördüm: var array = []; var push = array.push; var slice = array.slice; var splice = array.splice;Bunu @MathiasBynens bahsettiği güvenlik sorunu için yapıyor mu?
owensmartin

125

JavaScript'te, bir nesnenin yöntemleri çalışma zamanında başka bir nesneye bağlanabilir. Kısacası, javascript bir nesnenin başka bir nesnenin yöntemini "ödünç almasına" izin verir:

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'

callVe applybunu sağlayan fonksiyon nesnelerin yöntemleri (sıra JavaScript, fonksiyonlar nesnelerdir). Yani, kodunuzda NodeList öğesinin bir dizinin dilim yöntemini ödünç aldığını söyleyebilirsiniz. .slice()sonuç olarak başka bir dizi döndürür ve bu dizi daha sonra kullanabileceğiniz "dönüştürülmüş" dizi olur.


Javascript nesnesinin işlevleri için concept soyut kavram açıklaması üzerinde patlama. Şimdi,callArray.prototype aka'nın işlevi[].prototype .
Sourabh

29

Bu alır slicebir gelen işlevi Array. Daha sonra, bu işlevi çağırır, ancak sonucunu kullanan document.querySelectorAllolarak thisnesnenin yerine gerçek bir dizi.


19

Dizi benzeri nesneleri gerçek dizilere dönüştürmek için kullanılan bir tekniktir.

Bu nesnelerden bazıları şunlardır:

  • arguments fonksiyonlarda
  • NodeList (içeriğinin getirildikten sonra değişebileceğini unutmayın! Bu yüzden onları diziye dönüştürmek onları dondurmanın bir yoludur)
  • jQuery koleksiyonları, aka jQuery nesneleri (bazı doc: API , type , learn )

Bu birçok amaca hizmet eder, örneğin nesneler referansla geçirilirken diziler değere göre geçirilir.

Ayrıca, ilk argümanın 0atlanabileceğini, burada ayrıntılı bir açıklama yapıldığını unutmayın .

Ve bütünlük uğruna, jQuery.makeArray () vardır .


15

Fikri nasıl dönüştürmek document.querySelectorAll('a')bir gelen NodeList düzenli diziye?

Bu sahip olduğumuz kod,

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

Önce sökelim,

  []    // 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'

Adım: 1 callFonksiyonun yürütülmesi

  • İçinde call, thisArgargümanların geri kalanı dışında bir argüman listesine eklenir.
  • Şimdi işlev slice, thisdeğerini thisArg(dizi benzeri nesne geldiğinden document.querySelector) ve bağımsız değişken listesiyle bağlayarak çağrılır . ie] startiçeren argüman0

Adım: 2 sliceİçinde çağrılan işlevin yürütülmesicall

  • startBir değişkene atanacak solarak0
  • beri endolduğu undefined, this.lengthsaklanacaktıre
  • boş bir dizi bir değişkende saklanacaktır a
  • Yukarıdaki ayarları yaptıktan sonra aşağıdaki tekrarlama gerçekleşir

    while(s < e) {
      a.push(this[s]);
      s++;
    }
  • asonuç olarak doldurulmuş dizi döndürülür.

Not: Senaryomuzu daha iyi anlamak için, bağlamımız için gerekli olan bazı adımlar orijinal çağrı ve dilim algoritmasından yoksayılmıştır .


1
Çok güzel adım adım açıklama. Müthiş! Teşekkür ederim :)
kittu

1
Güzel bir açıklama.
NaveenDA

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'dan: Array.from (element.children) veya Array.from ({length: 5}) ile dizi oluşturun

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.