Es allí una manera más eficiente para convertir un HTMLCollection a una Matriz, distinta de la iteración a través de los contenidos de la recogida y manualmente empujando cada elemento en una matriz?

  • ¿Qué se entiende por «eficiente»? Si mejor rendimiento, un bucle for es generalmente más rápido que el de la Matriz.el prototipo.rebanada. Un bucle también funciona en una amplia variedad de navegadores (es decir, todos), así que por esos criterios es la «más eficiente». Y es muy poco código: for (var a=[], i=collection.length; i;) a[--i] = collection[i]; no tanto de un «con» lo que hay 🙂
  • Gracias – te daría +59k si pudiera! 😉
  • Buscando en actual rendimiento del navegador, rebanada en su mayoría ha atrapado con bucles en términos de rendimiento, excepto en Chrome. El uso de un número mayor de elementos ligeros y optimización del bucle, el los resultados son casi idénticos, excepto en Chrome donde un bucle es mucho más rápido.
  • He creado un jsperf prueba que se ve en ambos métodos que @harpo mencionadas, así como jquery, prueba de rendimiento. He encontrado jquery es ligeramente más lento que ambos métodos de javascript y de alto rendimiento que varía entre el js casos de prueba. Chrome 59.0.3071 / Mac OS X 10.12.5 prefiere utilizar Array.prototype.slice.call y Valiente (basado en Chrome 59.0.3071) no tiene prácticamente ninguna diferencia entre las dos pruebas de javascript a través de varias pistas. Consulte jsperf.com/htmlcollection-array-vs-jquery-children
InformationsquelleAutor Tom | 2008-10-21

7 Comentarios

  1. 567
    var arr = Array.prototype.slice.call( htmlCollection )

    tendrá el mismo efecto que el uso de los «nativos» de código.

    Editar

    Ya que este obtiene un montón de puntos de vista, nota (por @oriol comentario) que el siguiente más concisa expresión es efectivamente equivalente:

    var arr = [].slice.call(htmlCollection);

    Pero nota por @JussiR del comentario, que a diferencia de la «verbose» forma, se crea un vacío, sin usar, y de hecho inutilizable instancia de array en el proceso. ¿Qué compiladores hacer acerca de esto está fuera del programador ken.

    Editar

    Desde ECMAScript 2015 (ed 6) también hay Array.de:

    var arr = Array.from(htmlCollection);

    Editar

    ECMAScript 2015 también ofrece la la propagación del operador, que es funcionalmente equivalente a Array.from (aunque tenga en cuenta que Array.from soporta una función de asignación como el segundo argumento).

    var arr = [...htmlCollection];

    He confirmado que dos de los trabajos mencionados en NodeList.

    • Esto no funciona en IE
    • Esto no funciona en IE6.
    • no funciona hasta Internet Explorer 8.
    • El acceso directo [].slice.call(htmlCollection) también funciona.
    • Sí, yo estaba mal informado sobre eso. Lo siento por la difusión de ese todo. No me di cuenta de que me había indicado que aquí también. Eliminado el comentario para evitar la confusión, pero para el contexto que había leído (o malinterpretar) en algún lugar que cortar una HTMLCollection hecho se comportan como un array y una colección. Totalmente incorrecto.
    • Fwiw, el contenido de Oriol comentario también fue mencionado en @AUTO respuesta, debajo de alrededor de un mes anterior, si usted quiere difundir el karma de todo un poco.
    • El MDN docs para la Matriz.el prototipo.rebanada de tener una buena explicación de cuándo se debe utilizar este tipo de transformación, y un buen relleno para Internet Explorer < 9. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
    • var arr = [].rebanada.llame al(htmlCollection); falla en internet explorer 11, pero Matriz.prototipo todavía funciona
    • La [].rebanada de acceso directo no es equivalente, ya que también crea no utilizados vacío instancia de array. No estoy seguro si los compiladores son capaces de optimizar lejos, sin embargo.
    • buen punto, se señaló en la respuesta.
    • Gran. Gracias.
    • Array.from, es decir,from, no es compatible con IE11.
    • ¿Cómo funciona la Matriz.el prototipo.rebanada.llame al( htmlCollection) de trabajo? Alguien aquí puede explicar?
    • generalmente no se utiliza de esta manera. En su lugar, usted diría que es como un método en una matriz como [3, 5, 7].slice(). Que crea y devuelve una nueva Matriz basada en los índices pasa a slice. Cuando no se pasan argumentos, se copia toda la matriz. HTML colecciones no tienen Array en su cadena de prototipos, entonces usted no puede usar el slice método en las referencias a ellos. Sin embargo, si utiliza call() (que está en Function.prototype) para invocar Array.prototype.slice en una matriz-como objeto, se realiza la misma cosa. Espero que esto ayude!
    • la propagación operador no funciona, al menos no como esta: [...htmlColl].forEach((i)=>{//do})

  2. 77

    no estoy seguro si este es el más eficiente, pero concisa ES6 sintaxis puede ser:

    let arry = [...htmlCollection] 

    Edit: Otro uno, a partir de Chris_F comentario:

    let arry = Array.from(htmlCollection)
    • Además, ES6 añade Array.from()
    • Reloj hacia fuera para el primero, hay un error sutil cuando transpiling con babel donde […htmlCollection] devolverá un array con los htmlCollection como sólo elemento.
    • Matriz de propagación operador no funciona en htmlCollection. Es aplicable sólo a la lista de nodos.
    • Array.from, es decir,from, no es compatible con IE11.
    • Referencia se Parece a la propagación del operador es más rápido de estos 2.
    • [...htmlCollection] no funciona en Edge.

  3. 19

    Vi una forma más concisa método de obtención de Array.prototype métodos en general que funciona igual de bien. La conversión de un HTMLCollection objeto en un Array objeto se muestra a continuación:

    [].rebanada.llame al( yourHTMLCollectionObject ); 
    

    Y, como se ha mencionado en los comentarios, para los navegadores antiguos como internet explorer 7 y versiones anteriores, usted simplemente tiene que utilizar la compatibilidad de la función, como:

    function toArray(x) {
        for(var i = 0, a = []; i < x.length; i++)
            a.push(x[i]);
    
        return a
    }

    Sé que esto es una vieja pregunta, pero me sentí aceptada respuesta fue un poco incompleta; así que pensé en tirar esto a cabo no por lo que vale.

  4. 6

    Por una cruz de implementación del explorador me gustaría sugguest mirar prototype.js $A función

    copyed de la 1.6.1:

    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;
    }

    No uso Array.prototype.slice probablemente porque no está disponible en todos los navegadores. Me temo que el rendimiento es bastante malo ya que hay una de la caída de la espalda es un javascript lazo sobre la iterable.

    • El OP pidió otra forma de «iterar a través de los contenidos de la recogida y manualmente empujando cada elemento en una matriz», pero eso es precisamente lo que el $A función hace la mayor parte del tiempo.
    • Creo que el punto que estaba tratando de hacer es que no hay una buena manera de hacerlo, la prototype.js el código de muestra que puede buscar un ‘método toArray’ método, pero en su defecto de la iteración de la ruta más segura
    • Esto creará nuevas, indefinido miembros de matrices dispersas. Debe haber un hasOwnProperty de prueba antes de la asignación.
  5. 3

    Esta es mi solución personal, con base en la información aquí (este hilo):

    var Divs = new Array();    
    var Elemns = document.getElementsByClassName("divisao");
        try {
            Divs = Elemns.prototype.slice.call(Elemns);
        } catch(e) {
            Divs = $A(Elemns);
        }

    Donde $A fue descrito por Gareth Davis en su post:

    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;
    }

    Si el navegador soporta la mejor manera, aceptar, de lo contrario va a utilizar la cruz del navegador.

    • En general, no espero try/catch para ser una forma eficaz de administrar el flujo de control. Usted puede comprobar si la función existe en primer lugar, a continuación, ejecute uno o el otro, un poco más barato.
    • Como con Gareth Davis » respuesta, esto crea nuevas, indefinido miembros en matrices dispersas, por lo que [,,] se convierte en [undefined, undefined].
    • No tuve este tipo de problemas. Se las costuras de 3 elementos de la colección de resultados en una matriz de 2 elementos. Como para vacío convertido en indefinido, es un poco de JavaScript limitaciones, me ges esperando null en lugar de definir, a la derecha?
  6. 3

    Esto funciona en todos los navegadores incluyendo las anteriores versiones de IE.

    var arr = [];
    [].push.apply(arr, htmlCollection);

    Desde jsperf está todavía en el momento, aquí es un jsfiddle que compara el rendimiento de los diferentes métodos. https://jsfiddle.net/qw9qf48j/

    • trate de var args = (htmlCollection.length === 1 ? [htmlCollection[0]] : Array.apply(null, htmlCollection));
  7. 3

    Para convertir la matriz semejante a la matriz en forma eficiente en la que podemos hacer uso de la jQuery makeArray :

    makeArray: Convertir una matriz-como objeto de un verdadero array de JavaScript.

    Uso:

    var domArray = jQuery.makeArray(htmlCollection);

    Un poco más:

    Si usted no desea mantener la referencia a la matriz de objetos (la mayoría del tiempo HTMLCollections se cambia dinámicamente por lo que su mejor copiarlos en otra matriz, en Este ejemplo se preste mucha atención al rendimiento:

    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.
    }

    ¿Qué es la matriz-como?

    HTMLCollection es un "array-like" objeto, el matriz-como objetos son similares a los de la matriz de objeto, pero faltan un montón de su funcionalmente definición:

    Matriz-al igual que los objetos se vean como los arrays. Ellos tienen varias numerado
    elementos y una longitud de propiedad. Pero ahí es donde la similitud se detiene.
    Matriz-al igual que los objetos no tienen ninguna de la Matriz de funciones, y en
    los bucles no trabajo!

Dejar respuesta

Please enter your comment!
Please enter your name here