Mees doeltreffende manier om 'n HTMLCollection te skakel na 'n skikking
-
03-07-2019 - |
Vra
Is daar 'n meer doeltreffende manier om 'n HTMLCollection te skakel na 'n skikking, behalwe iterating deur die inhoud van die genoemde versameling en elke item met die hand stoot in 'n skikking?
Oplossing
var arr = Array.prototype.slice.call( htmlCollection )
sal dieselfde effek hê met behulp van "inheemse" kode.
Edit
Aangesien dit kry 'n baie menings, kennis (per comment @ Oriol se) wat die volgende meer bondige uitdrukking is effektief ekwivalent:
var arr = [].slice.call(htmlCollection);
Maar noot per @ JussiR se kommentaar, wat in teenstelling met die "verbose" vorm, beteken dit 'n leë, ongebruikte, en inderdaad onbruikbaar verskeidenheid byvoorbeeld skep in die proses. Wat opstellers doen oor hierdie is buite die programmeerder se Ken.
Edit
Sedert ECMAScript 2015 (ed 6) is daar ook Array.from
var arr = Array.from(htmlCollection);
Edit
ECMAScript 2015 bied ook die verspreiding operateur , wat is funksioneel gelykstaande aan Array.from
(hoewel kennis dat Array.from
ondersteun 'n kartering funksie as die tweede argument).
var arr = [...htmlCollection];
Ek het bevestig dat beide van die bogenoemde werk op NodeList
.
Ander wenke
nie seker of dit is die mees doeltreffende, maar 'n bondige ES6 sintaksis dalk:
let arry = [...htmlCollection]
Edit: Nog een, uit Chris_F kommentaar:
let arry = Array.from(htmlCollection)
Ek het 'n meer bondige metode om Array.prototype
metodes in die algemeen dat werk net so goed. Omskakeling n HTMLCollection
voorwerp in 'n Array
voorwerp word hieronder getoon:
[].slice.call( yourHTMLCollectionObject );
En, soos genoem in die kommentaar, vir ou blaaiers soos IE7 en vroeër, jy eenvoudig moet 'n fisiese verenigbaarheidstoets funksie te gebruik, soos:
function toArray(x) {
for(var i = 0, a = []; i < x.length; i++)
a.push(x[i]);
return a
}
Ek weet dit is 'n ou vraag, maar ek het gevoel die aanvaarde antwoord was 'n bietjie onvolledig; so ek het gedink ek wil hierdie uitgooi daar FWIW.
Vir 'n kruis implementering leser Ek sal sugguest jy kyk na prototype.js $A
funksie
function $A(iterable) {
if (!iterable) return [];
if ('toArray' in Object(iterable)) return iterable.toArray();
var length = iterable.length || 0, results = new Array(length);
while (length--) results[length] = iterable[length];
return results;
}
Dit maak nie gebruik Array.prototype.slice
waarskynlik omdat dit nie beskikbaar is nie op elke leser. Ek is bevrees die prestasie is baie sleg as daar 'n die val terug is 'n javascript lus oor die iterable
.
Dit is my persoonlike oplossing, gebaseer op die inligting hier (hierdie draad):
var Divs = new Array();
var Elemns = document.getElementsByClassName("divisao");
try {
Divs = Elemns.prototype.slice.call(Elemns);
} catch(e) {
Divs = $A(Elemns);
}
Waar $ A beskryf deur Gareth Davis in sy pos:
function $A(iterable) {
if (!iterable) return [];
if ('toArray' in Object(iterable)) return iterable.toArray();
var length = iterable.length || 0, results = new Array(length);
while (length--) results[length] = iterable[length];
return results;
}
As leser is die beste manier ondersteun, ok, anders sal die kruis leser gebruik.
Dit werk in alle blaaiers, insluitend vroeër Internet Explorer weergawes.
var arr = [];
[].push.apply(arr, htmlCollection);
Sedert jsperf is nog steeds af op die oomblik, hier is 'n jsfiddle dat die prestasie van verskillende metodes vergelyk. https://jsfiddle.net/qw9qf48j/
Om verskeidenheid-agtige skakel na verskeidenheid in doeltreffende manier kan ons gebruik maak van die jQuery makeArray
:
makeArray:. Skakel 'n skikking-agtige voorwerp in 'n ware JavaScript verskeidenheid
Gebruik:
var domArray = jQuery.makeArray(htmlCollection);
'n bietjie ekstra:
As jy nie wil hê om verwysing na die verskeidenheid voorwerp (die meeste van die tyd HTMLCollections is dinamies te hou verander sodat sy beter om hulle in 'n ander verskeidenheid kopieer, Hierdie voorbeeld aandag skenk aan prestasie:
var domDataLength = domData.length //Better performance, no need to calculate every iteration the domArray length
var resultArray = new Array(domDataLength) // Since we know the length its improves the performance to declare the result array from the beginning.
for (var i = 0 ; i < domDataLength ; i++) {
resultArray[i] = domArray[i]; //Since we already declared the resultArray we can not make use of the more expensive push method.
}
Wat is opgestel-agtige?
HTMLCollection is 'n "array-like"
voorwerp, die skikking-agtige voorwerpe is soortgelyk aan voorwerp reeks se maar ontbreek 'n baie van sy funksioneel definisie:
Array-agtige voorwerpe lyk skikkings. Hulle het verskeie genommerde elemente en 'n lengte eiendom. Maar dit is waar die ooreenkoms tot stilstand kom. Verskeidenheid-agtige voorwerpe nie enige van funksies verskeidenheid's het, en vir-in loops nie eens werk!