Pregunta

Me encontré con el siguiente código:

var f = function () {
    var args = Array.prototype.slice.call(arguments).splice(1);

    // some more code 
};

Básicamente, el resultado en args es una matriz que es una copia de la arguments sin su primer elemento.

Pero lo que no puedo entender exactamente es la razón por f de arguments (que es un objeto que contiene los argumentos introducidos de la función en un objeto de matriz similar) objeto se pasa al método slice y cómo slice(1) está quitando el primer elemento ( posicionado en el índice 0).

Puede alguien explicar por favor por mí?

P.S. El código es de esta función de aplicación parcial

¿Fue útil?

Solución


El código real de que ligado respuesta es:

var args = Array.prototype.slice.call(arguments, 1);

es decir. "Rebanada", no "empalme"

En primer lugar, el método slice se utiliza a menudo para hacer una copia de la matriz se llama en :

var a = ['a', 'b', 'c'];
var b = a.slice();  // b is now a copy of a
var c = a.slice(1); // c is now ['b', 'c']

Así que la respuesta corta es que el código es, básicamente, emulando:

arguments.slice(1); // discard 1st argument, gimme the rest

Sin embargo, no puede hacerlo directamente. Los href="https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope/arguments" especial objeto arguments (disponible dentro del contexto de ejecución de todas las funciones de JavaScript ), aunque Expandido como en la que se apoya la indexación a través del operador [] con las teclas numéricas, no es en realidad una matriz; No se puede .push en él, .pop fuera de él, o que .slice, etc.

La forma del código logra esto es por "engañar" la función slice (que de nuevo no se encuentra disponible en el objeto arguments) para ejecutar en el contexto de arguments, a través de Function.prototype.call :

Array.prototype.slice // get a reference to the slice method
                      // available on all Arrays, then...
  .call(              // call it, ...
    arguments,        // making "this" point to arguments inside slice, and...
    1                 // pass 1 to slice as the first argument
  )

Array.prototype.slice.call(arguments).splice(1) logra la misma cosa, pero hace una llamada ajena a splice(1), que elimina elementos de la matriz de regresar de Array.prototype.slice.call(arguments) comenzando en el índice 1 y continuando hasta el final de la matriz. splice(1) no funciona en IE (que es técnicamente perder un segundo parámetro diciendo que el número de elementos a eliminar que el IE y ECMAScript requieren).

Otros consejos

var args = Array.prototype.slice.call(arguments).splice(1);

En primer lugar se lleva una copia de arguments (*), a continuación, elimina todo menos el primer elemento de ella (de un modo no estándar), y asigna esos artículos que son removidos para args.

La matriz adicional que se produce, a continuación, altera y se tira es bastante redundante. Sería mejor decir - como la versión de la respuesta se ha vinculado a hecho hace:

var args = Array.prototype.slice.call(arguments, 1);

aplicación de función parcial es también una característica del método function.bind, siendo normalizado por el ECMAScript Quinta edición. Hasta navegadores han implementado, se puede recoger una versión de un repliegue JS-nativa de la parte inferior de la esta respuesta .

*: array.slice() es el lenguaje normal para copiar una matriz, y array.slice(1) para la toma de la cola. Se tiene que ser llamada explícita a través de la Array.prototype porque arguments no es un conjunto, a pesar de que se parece a uno, por lo que no tiene los métodos de arreglos normales. Este es otro de los errores extraños de JavaScript.

Se ve muy a menudo las personas que utilizan los métodos Array.prototype en objetos que no son matrices; el estándar ECMAScript tercera edición se sale de su manera de decir que esto está bien que hacer para la matriz como arguments, pero no que también puede hacerlo en otras array-le gusta que pueden ser objetos de acogida, tales como NodeList o HTMLCollection. Aunque es posible que salirse con la llamada a métodos Array.prototype en un no-Array en muchos navegadores de hoy en día, el único lugar en realidad es seguro hacerlo está en arguments.

El valor devuelto de un empalme es una matriz de los elementos que se han eliminado, pero la matriz original (o matriz como objeto), se trunca en el índice de empalme.

Realización de una copia con la rebanada conserva la matriz argumentos originales, presumiblemente para su uso posterior en la función.

En este caso el mismo resultado se puede tener con args = [].slice.call(arguments, 1)

function handleArguments(){
 var A= [].slice.call(arguments).splice(1);
 //arguments is unchanged
 var s= 'A='+A+'\narguments.length='+arguments.length;

 var B= [].splice.call(arguments, 1);
 // arguments now contains only the first parameter
 s+= '\n\nB='+B+'\narguments.length='+arguments.length;
 return s;
}

// test
alert(handleArguments(1, 2, 3, 4));

returned value:
//var A= [].slice.call(arguments).splice(1);
A=2,3,4
arguments.length=4

//var B= [].splice.call(arguments, 1);
B=2,3,4
arguments.length=1
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top