ES6'da nod listelerini filtreleyin veya eşleyin


90

ES6'da bir düğüm listesini filtrelemenin veya eşleştirmenin en etkili yolu nedir?

Okumalarıma göre aşağıdaki seçeneklerden birini kullanırdım:

[...nodelist].filter

veya

Array.from(nodelist).filter

Hangisini önerirsiniz? Ve örneğin dizileri dahil etmeden daha iyi yollar var mı?


2
Temel olarak, her iki yöntem de aynı şeyi yapar. Kullandığınız şey babel, o [...coll]zaman basitçe Array.from(coll)olmayan herhangi bir şeyi arayacaktır Array.
Leonid Beschastny

FWIW, ...sözdizimi eski IDE'ler tarafından desteklenmezken Array.from(), sadece normal bir yöntem olabilir.
Marat Tanalin

Yanıtlar:


131
  • [...nodelist] nesne yinelenebiliyorsa, nesneden bir dizi oluşturur.
  • Array.from(nodelist)nesne yinelenebilirse veya nesne dizi benzeri ise (has .lengthve sayısal props) bir nesneden bir dizi oluşturur

Varsa NodeList.prototype[Symbol.iterator], iki örneğiniz aynı olacaktır , çünkü her iki durum da yinelemeleri kapsar. NodeListOrtamınız yinelenebilir şekilde yapılandırılmamışsa , ilk örneğiniz başarısız olur ve ikincisi başarılı olur. Babelşu anda bu durumu düzgün bir şekilde ele almıyor .

Dolayısıyla, eğer NodeListtekrarlanabilirse, hangisini kullanacağın gerçekten sana kalmış. Muhtemelen duruma göre seçerdim. Bunun bir yararı, Array.frombir eşleme fonksiyonunun ikinci bir argümanını almasıdır, oysa ilkinin [...iterable].map(item => item)geçici bir dizi yaratması gerekir, Array.from(iterable, item => item)bu değildir. Ancak listeyi eşlemiyorsanız, önemli değil.


17

TL; DR;

Array.prototype.slice.call(nodelist).filter

Slice () yöntemi bir dizi döndürür. Dönen dizi toplama (nodelist) sığ bir kopyasıdır Yani daha hızlı daha çalışır Yani Array.from () o kadar hızlı çalışır Yani ) (Array.from

Orijinal koleksiyonun öğeleri döndürülen diziye şu şekilde kopyalanır:

  • Nesne referansları için (gerçek nesne değil), nesne referanslarını yeni diziye kopyalar. Hem orijinal hem de yeni dizi aynı nesneyi ifade eder. Referans verilen bir nesne değişirse, değişiklikler hem yeni hem de orijinal diziler tarafından görülebilir.
  • Dizeler, sayılar ve boole'lar için (String, Number ve Boolean nesneleri değil), dilim, değerleri yeni diziye kopyalar. Bir dizideki dize, sayı veya boole'de yapılan değişiklikler diğer diziyi etkilemez.

Argümanlarla ilgili kısa açıklama

Array.prototype.slice (beginIndex, endIndex)

  • isteğe bağlı argümanları beginIndex ve endIndex alır. Sağlanmazsa dilimler beginIndex == 0 kullanır, böylece koleksiyondaki tüm öğeleri çıkarır.

Array.prototype.slice.call (ad alanı, beginIndex, endIndex)

  • ilk argüman olarak bir nesneyi alır. Bir koleksiyonu bir nesne olarak kullanırsak, bu kelimenin tam anlamıyla, slice yöntemini doğrudan o nesne ad alanından çağırdığımız anlamına gelir.slice ()

2
Sınırlı ve anında yardım sağlayabilecek bu kod parçacığı için teşekkür ederiz. Uygun bir açıklama, bunun neden soruna iyi bir çözüm olduğunu göstererek uzun vadeli değerini büyük ölçüde artıracak ve diğer benzer sorularla gelecekteki okuyucular için daha yararlı hale getirecektir. Yaptığınız varsayımlar da dahil olmak üzere bazı açıklamalar eklemek için lütfen cevabınızı düzenleyin.
Maximilian Peters

O zamandan beri IE desteğine sahip olup olmadığını merak ediyorum Array.from. Bir IE makinesi bulma zamanı. Şimdi gerçekten kafam karıştı çünkü Array.from'u IE10 ve IE11'de kullanabildim: \. Bu yöntem IE10 + 11'de işe yarıyor, ancak Array.f tarafından tüm belgeler aksini söylediğinde çalışmaktan rahatlamadım.
CTS_AE

Array.fromIE11'de benim için çalışmıyor Nesne özelliği veya yöntemi 'itibaren' desteklemiyor
Fus Ro Dah

Teşekkürler, bu benim için eski bir JavaScript uygulaması üzerinde çalıştı
Vic Seedoubleyew

1
Array.fromsığ bir kopya da döndürür. Sana nasıl görmüyorum Yani sonuçlandırmak daha hızlı daha çalışır Array#slice.
Robert

9

Doğrudan NodeList üzerinde kullanan bir referans buldum map.

Array.prototype.map.call(nodelist, fn)

Test etmedim, ancak bunun daha hızlı olacağı mantıklı görünüyor çünkü doğrudan NodeList'e erişmesi gerekiyor.


4

Buna ne dersin:

// Be evil. Extend the prototype.
if (window.NodeList && !NodeList.prototype.filter) {
  NodeList.prototype.filter = Array.prototype.filter;
}

// Use it like you'd expect:
const noClasses = document
  .querySelectorAll('div')
  .filter(div => div.classList.length === 0)

NodeList.forEach için MDN belgelerinde belirtilen yaklaşımın aynısıdır ('Polyfill' altında), IE11 , Edge, Chrome ve FF için çalışır.


hafif bir uyarı, şimdi nodeList.filter size bir düğüm listesi yerine bir dizi verecektir. sorun olmamalı, ama unutması kolay ^^
hanshenrik
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.