Une question sur les méthodes slice et splice de JavaScript

j'ai trouvé le code suivant:

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

    // some more code 
};

fondamentalement, le résultat dans args est un tableau qui est une copie du arguments sans son premier élément.

mais ce que je ne peux pas comprendre exactement est pourquoi f 's arguments (qui est un objet qui tient les arguments entrés de la fonction dans un objet de type tableau) objet est passé à la méthode slice et comment slice(1) supprime la première élément (positionné à l'index 0).

quelqu'un peut-il me l'expliquer?

P. S. le code est de cette fonction d'application partielle

23
demandé sur Community 2009-11-22 06:10:46

3 réponses



Le code réel de cette réponse liée est:

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

c'est à dire "tranche", pas de "splice"

< / Note>

tout d'abord, la méthode slice est souvent utilisée pour faire une copie du tableau il est appelé sur :

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']

donc la réponse courte est que le code émule fondamentalement:

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

mais vous ne pouvez pas le faire directement. Le spécial arguments objet (disponible dans le contexte d'exécution de toutes les fonctions JavaScript), bien que le tableau - comme en ce qu'il soutient l'indexation via l'opérateur [] avec des clés numériques, n'est pas en fait un tableau; vous ne pouvez pas .push sur elle, .pop hors elle, ou .slice Elle, etc.

le code pour ce faire , il faut "tromper" la fonction slice (qui n'est pas non plus disponible sur l'objet arguments ) pour exécuter dans le contexte de arguments , via 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) accomplit la même chose, mais fait un appel externe à splice(1) , qui supprime éléments du tableau retourné de Array.prototype.slice.call(arguments) à partir de l'index 1 et continue à la fin du tableau. splice(1) ne fonctionne pas dans IE (il manque techniquement un 2e paramètre indiquant combien d'éléments pour supprimer ce QU'IE et ECMAScript exigent).

40
répondu Crescent Fresh 2017-05-23 12:25:13
var args = Array.prototype.slice.call(arguments).splice(1);

prend D'abord une copie de arguments ( * ), puis enlève tous les articles sauf le premier (de manière non standard), et assigne ces articles étant enlevés à args .

le tableau supplémentaire étant produit, puis modifié et jeté est tout à fait redondant. Il vaudrait mieux dire - comme le fait la version de la réponse à laquelle vous avez fait référence:

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

application de fonction partielle est également une caractéristique de la Méthode function.bind , standardisée par la cinquième édition D'ECMAScript. Jusqu'à ce que les navigateurs l'ont mis en œuvre, vous pouvez prendre une version de repli js-native à partir du bas de cette réponse .

*: array.slice() est l'idiome normal pour copier un tableau, et array.slice(1) pour prendre la queue. Il a été appelé explicitement par le Array.prototype parce que arguments n'est pas un tableau, même s'il ressemble à un, donc n'a pas la normale les méthodes de tableau. C'est une autre des erreurs bizarres de JavaScript.

vous voyez souvent des gens utiliser les méthodes Array.prototype sur des objets qui ne sont pas des tableaux; le standard de la troisième édition D'ECMAScript sort de son chemin pour dire que c'est correct de faire pour le arguments comme tableau, mais pas que vous pouvez aussi le faire sur d'autres types de tableau qui peuvent être des objets hôtes, tels que NodeList ou HTMLCollection. Bien que vous pourriez vous en tirer avec l'appel Array.prototype méthodes sur un non-tableau dans de nombreux navigateurs aujourd'hui, le seul endroit où il est réellement sécuritaire de le faire est sur arguments .

3
répondu bobince 2017-05-23 12:09:17

la valeur retournée d'un raccord est un tableau des éléments qui ont été enlevés, mais le tableau original (ou objet similaire à un tableau), est tronqué à l'index splice.

faire une copie avec slice préserve le tableau d'arguments original, sans doute pour une utilisation ultérieure dans la fonction.

Dans ce cas, le même résultat peut être obtenu avec 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
0
répondu kennebec 2009-11-22 12:23:40