Me topé con este atajo ordenado para convertir un DOM NodeList en una matriz regular, pero debo admitir que no entiendo completamente cómo funciona:
[].slice.call(document.querySelectorAll('a'), 0)
Entonces comienza con una matriz vacía []
, luego slice
se usa para convertir el resultado call
en una nueva matriz, ¿sí?
Lo poco que no entiendo es el call
. ¿Cómo se convierte eso document.querySelectorAll('a')
de una NodeList a una matriz regular?
javascript
arrays
call
slice
Yansky
fuente
fuente
Array.prototype.slice.call(document.querySelectorAll('a'));
es una forma adecuada de escribir el fragmento de código que escribió.Array.from
. Entonces, por ejemplo, esto haría lo mismo: Array.from (document.querySelectorAll ('a'));Respuestas:
Lo que sucede aquí es que llamas
slice()
como si fuera una función delNodeList
usocall()
. Lo queslice()
hace en este caso es crear una matriz vacía, luego iterar a través del objeto en el que se está ejecutando (originalmente una matriz, ahora aNodeList
) y seguir agregando los elementos de ese objeto a la matriz vacía que creó, que finalmente se devuelve. Aquí hay un artículo sobre esto .EDITAR:
Eso no está bien.
[].slice
devuelve un objeto de función. Un objeto de función tiene una funcióncall()
que llama a la función que asigna el primer parámetro decall()
tothis
; en otras palabras, hacer que la función piense que se llama desde el parámetro (NodeList
devuelto pordocument.querySelectorAll('a')
) en lugar de desde una matriz.fuente
Array.prototype.slice.call(...)
, en realidad crea una instancia de un objeto de matriz ([]
) solo para acceder a su método de corte prototipo. Esa es una instanciación desperdiciada. Decir que enArray.prototype.slice.call(...)
cambio es más limpio, aunque agregue varios caracteres a su JS si está contando ...NodeList
s[]
es más confiable ya queArray
podría sobrescribirse a otra cosa. Si necesita reutilizarArray#slice
, es una buena idea guardarlo en caché.var array = []; var push = array.push; var slice = array.slice; var splice = array.splice;
¿Hace esto por el problema de seguridad que menciona @MathiasBynens?En JavaScript, los métodos de un objeto pueden vincularse a otro objeto en tiempo de ejecución. En resumen, javascript permite que un objeto "tome prestado" el método de otro objeto:
Los métodos
call
yapply
de los objetos de función (en JavaScript, las funciones también son objetos) le permiten hacer esto. Entonces, en su código, podría decir que NodeList está tomando prestado el método de división de una matriz..slice()
devuelve otra matriz como resultado, que se convertirá en la matriz "convertida" que luego puede usar.fuente
call
función deArray.prototype
aka[].prototype
usted mismo.Recupera la
slice
función de unArray
. Luego llama a esa función, pero usa el resultado dedocument.querySelectorAll
como elthis
objeto en lugar de una matriz real.fuente
Es una técnica para convertir objetos tipo matriz en matrices reales.
Algunos de estos objetos incluyen:
arguments
en funcionesEsto sirve para muchos propósitos, por ejemplo, los objetos se pasan por referencia, mientras que las matrices se pasan por valor.
Además, tenga en cuenta que el primer argumento
0
se puede omitir, una explicación detallada aquí .Y en aras de la integridad, también hay jQuery.makeArray () .
fuente
Este es el código que tenemos,
Vamos a desmontarlo primero
Paso: 1 Ejecución de la
call
funcióncall
, aparte delthisArg
, el resto de los argumentos se agregarán a una lista de argumentos.slice
se invocará la función al vincular suthis
valor comothisArg
(matriz de la que proviene el objetodocument.querySelector
) y con la lista de argumentos. es decir] argumentostart
que contiene0
Paso: 2 Ejecución de la
slice
función invocada dentro decall
start
será asignado a una variables
como0
end
esundefined
,this.length
serán almacenados ene
a
Después de realizar la configuración anterior, se realizará la siguiente iteración
a
se devolverá como resultado.PD Para una mejor comprensión de nuestro escenario, algunos pasos que son necesarios para nuestro contexto han sido ignorados del algoritmo original de llamada y corte .
fuente
fuente
Desde ES6: simplemente cree una matriz con Array.from (element.children) o Array.from ({length: 5})
fuente