javascript - Filtrera eller mappa nodelists i ES6


Vad är det mest effektiva sättet att filtrera eller mappa en nodelist i ES6?

Baserat på mina läsningar skulle jag använda ett av följande alternativ:

[...nodelist].filter

eller

Array.from(nodelist).filter

Vilken skulle du rekommendera? Och finns det bättre sätt, till exempel utan att involvera arrayer?

Svar #1

  • [...nodelist] kommer att skapa en array från ett objekt om objektet är itererbart.
  • Array.from(nodelist) kommer att skapa en array av ett objekt om objektet är itererbart eller om objektet är array-liknande (har .length och numeriska egenskaper)

Dina två exempel kommer att vara identiska om NodeList.prototype[Symbol.iterator] existerar, eftersom båda fallen täcker itererbara objekt. Om din miljö dock inte har konfigurerats så att NodeList är itererbar, kommer ditt första exempel att misslyckas och det andra att lyckas. Babel hanterar för närvarande inte detta fall korrekt.

Så om din NodeList är itererbar är det egentligen upp till dig vilken du använder. Jag skulle sannolikt välja från fall till fall. En fördel med Array.from är att den tar ett andra argument som är en kartläggningsfunktion, medan den första [...iterable].map(item => item) skulle behöva skapa en temporär array, Array.from(iterable, item => item) skulle inte behöva det. Om du däremot inte kartlägger listan spelar det ingen roll.

Svar #2

Jag hittade en referens som använder map direkt på NodeList genom

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

Jag har inte testat det, men det verkar rimligt att detta skulle vara snabbare eftersom det borde komma åt NodeList direkt.

Svar #3

Sammanfattning

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

Metoden slice() returnerar en array. Den returnerade arrayen är en ytlig kopia av samlingen (NodeList) Så den fungerar snabbare än Array.from() Så den fungerar lika snabbt som Array.from()

Element från den ursprungliga samlingen kopieras till den returnerade arrayen på följande sätt:

  • För objektreferenser (och inte det faktiska objektet) kopierar slice objektreferenser till den nya arrayen. Både den ursprungliga och den nya arrayen refererar till samma objekt. Om ett refererat objekt ändras är ändringarna synliga för både den nya och den ursprungliga arrayen.
  • För strängar, nummer och booleaner (inte String-, Number- och Boolean-objekt), kopierar slice värdena till den nya arrayen. Ändringar i strängen, numret eller booleanen i en array påverkar inte den andra arrayen.

Kort förklaring angående argument

Array.prototype.slice(beginIndex, endIndex)

  • tar valfria argumenten beginIndex och endIndex. Om de inte anges använder slices beginIndex == 0, och extraherar därmed alla objekt från samlingen

Array.prototype.slice.call(namespace, beginIndex, endIndex)

  • tar ett objekt som det första argumentet. Om vi använder en samling som ett objekt betyder det bokstavligen att vi kallar på slice-metoden direkt från det objektet namespace.slice()

Relaterade artiklar