2011-02-28 12 views
46

Estaba navegando código fuente de chisporroteo y me encontré con esta línea de código:¿De qué sirve Array.prototype.slice.call (array, 0)?

array = Array.prototype.slice.call(array, 0); 

Miré lo que la función es, pero llegaron a la conclusión de que simplemente devuelve todos los elementos de la matriz a partir de índice 0, y pone el todo en la matriz, es decir, realmente no hace nada en absoluto.

¿Cuál es el uso de esta línea de código? ¿Qué me estoy perdiendo?

Edit: Es la línea 863 de https://github.com/jquery/sizzle/blob/master/sizzle.js#L863.

+1

Parece una manera un tanto colmada de llamar a 'array.slice (0)', que haría una copia de la matriz. Sin embargo, no entiendo por qué se lo está llamando de una manera tan impenetrable. – spender

+8

El contexto hace toda la diferencia. El identificador 'array' no hace referencia a una matriz real. – user113716

Respuesta

75

El DOM generalmente devuelve NodeList para la mayoría de las operaciones como getElementsByTagName.

Aunque un NodeList casi se siente como una matriz, no lo es. Tiene una propiedad length, como una matriz, y un método item(index) para acceder a un objeto en el índice dado (también accesible con la notación [index]), pero ahí termina la similitud.

Para poder utilizar el maravilloso array methods sin reescribirlos todos para un NodeList, la línea anterior es útil.

Otro uso de convertirlo en una matriz es hacer la lista estática. Las listas de nodos suelen estar activas, lo que significa que si se producen cambios en el documento, el objeto NodeList se actualiza automáticamente. Eso podría causar problemas, si un objeto jQuery devuelto cambia constantemente debajo de tu nariz. Pruebe el siguiente snippet para probar la vida de NodeLists.

var p = document.getElementsByTagName('p'); 
console.log(p.length); // 2 
document.body.appendChild(document.createElement('p')); 
// length of p changes as document was modified 
console.log(p.length); // 3 
+3

Mierda esta respuesta me lleva un paso más cerca de abrazar a JS. He estado esperando durante años que simplemente desaparecería ... +1 para ti de todos modos. – Lee

+0

Una pregunta que tuve que surgió fue: ¿cómo sabes a qué objetos se pueden aplicar los métodos de matriz? Aparentemente, es cualquier objeto con una propiedad de longitud y nombres de propiedad enteros (¿que comienzan desde cero?). También aprendí que la variable "arguments" es una matriz como objeto, pero no una matriz real (no lo sabía). La respuesta estaba aquí: http://stackoverflow.com/questions/7056925/how-does-array-prototype-slice-call-work – zod

+1

@zod: si nos fijamos en la implementación de [V8] (http://code.google .com/p/v8/source/browse/trunk/src/array.js # 617) luego allí [no parece] (http://code.google.com/p/v8/source/browse/trunk/ src/array.js # 321) para que ocurra algo mágico. Utiliza '.length' para determinar el rango y luego hace un ciclo' for' para copiar los elementos correctos (que solo requieren un objeto con teclas numéricas). – pimvdb

6

Como dice BoltClock, hace una copia (superficial) de una matriz. También se puede usar para copiar algo que es casi una matriz, como arguments incorporada, que tiene una longitud y elementos pero no una matriz en su cadena de prototipos (y, por tanto, no hay un método de división).

+0

Eso creía, pero asigna el resultado al mismo 'arreglo', por lo que no puedo entender qué está pasando realmente. – BoltClock

+0

¿Puedo preguntar por qué 'var' no se pone antes? Si se realiza una copia, ¿no sería una nueva variable, es decir, con 'var'? – pimvdb

+0

@BoltClock, Hmmm ... eso es extraño. Tal vez sea para dar el prototipo de Array a algo que no es realmente, como argumentos o un conjunto jQuery. – harpo

10

Lo que está sucediendo aquí es que Sizzle está creando una matriz real a partir de un objeto similar a una matriz. El objeto similar a una matriz no tiene necesariamente el método slice(), por lo que el método prototipo debe invocarse directamente. makeArray() devuelve una copia de ese objeto similar a una matriz que es una matriz real, y se puede usar como tal en donde.

Consulte here para obtener más información acerca de los objetos tipo array.