Est-il possible d'obtenir tous les arguments d'une fonction en tant qu'objet unique à l'intérieur de cette fonction?


Réponses:


346

Utilisez arguments. Vous pouvez y accéder comme un tableau. Utilisez arguments.lengthpour le nombre d'arguments.


46
Cela ne fonctionne que pour le JavaScript traditionnel function, pas pour les =>fonctions de flèche ES2015 + . Pour ceux -ci , vous voulez utiliser ...argsdans la définition de la fonction comme ceci: (...args) => console.log(args).
— Sawtaytoes

141

Les arguments sont un objet de type tableau (pas un tableau réel). Exemple de fonction ...

function testArguments () // <-- notice no arguments specified
{
    console.log(arguments); // outputs the arguments to the console
    var htmlOutput = "";
    for (var i=0; i < arguments.length; i++) {
        htmlOutput += '<li>' + arguments[i] + '</li>';
    }
    document.write('<ul>' + htmlOutput + '</ul>');
}

Essaye le...

testArguments("This", "is", "a", "test");  // outputs ["This","is","a","test"]
testArguments(1,2,3,4,5,6,7,8,9);          // outputs [1,2,3,4,5,6,7,8,9]

Les détails complets: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments


3
Pourquoi ne pas poster le résultat ici aussi? :)
— Jonathan Azulay

2
C'est beaucoup mieux que la réponse acceptée car elle contient un extrait de code de travail et affiche la sortie. La réponse acceptée est trop clairsemée.
— Mac

Une bonne réponse ... serait une excellente réponse en développant "pas un tableau réel"
— terpinmd

J'ai ajouté un lien vers une description simple: un "objet de type tableau" est juste un "objet qui a une propriété de longueur d'un entier non négatif, et généralement quelques propriétés indexées." Du lien mozilla: "Il est similaire à un tableau, mais n'a pas de propriétés de tableau à l'exception de la longueur."
— Luke

31

ES6 autorise une construction dans laquelle un argument de fonction est spécifié avec une notation "..." telle que

function testArgs (...args) {
 // Where you can test picking the first element
 console.log(args[0]); 
}

3
Cela semble être le seul moyen lors de l'utilisation de la fonction flèche. a = () => {console.log(arguments);}; a('foo');donne -- Uncaught ReferenceError: arguments is not defined Cependant a = (...args) => {console.log(args);}; a('foo');donne["foo"]
— David Baucum

1
@DavidBaucum qui est correct. Parce que la fonction flèche ne crée pas de nouvelle étendue et que les "arguments" sont collectés à partir de l'étendue. Mais le pire des cas n'est pas une ReferenceError. C'est que les "arguments" sont collectés à partir d'une portée externe. Ensuite, vous n'obtenez aucune exception, et peut-être des bugs étranges dans votre application.
— pgsandstrom

1
Ceci est également appelé "paramètres de repos", voir developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… .
— Dennis

21

le arguments objet est l'endroit où les arguments des fonctions sont stockés.

L'objet arguments agit et ressemble à un tableau, il l'est fondamentalement, il n'a tout simplement pas les méthodes utilisées par les tableaux, par exemple:

Array.forEach(callback[, thisArg]);

Array.map(callback[, thisArg])

Array.filter(callback[, thisArg]);

Array.slice(begin[, end])

Array.indexOf(searchElement[, fromIndex])

Je pense que la meilleure façon de convertir un argumentsobjet en un vrai tableau est la suivante:

argumentsArray = [].slice.apply(arguments);

Cela en fera un tableau;

réutilisable:

function ArgumentsToArray(args) {
    return [].slice.apply(args);
}

(function() {
   args = ArgumentsToArray(arguments);

   args.forEach(function(value) {
      console.log('value ===', value);
   });

})('name', 1, {}, 'two', 3)

résultat:

> value === name
> value === 1
> value === Object {}
> value === two
>value === 3


1
[].slice.apply(arguments);ne peut pas être le meilleur moyen car il provoque une allocation de tableau vide inutile.
— Thomas Eding

10

Vous pouvez également le convertir en tableau si vous préférez. Si des génériques de tableau sont disponibles:

var args = Array.slice(arguments)

Autrement:

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

de Mozilla MDN :

Vous ne devez pas trancher les arguments car cela empêche les optimisations dans les moteurs JavaScript (V8 par exemple).


2
Merci pour la mise à jour. Utilisez JSON.stringify et JSON.parse comme alternative: function foo() { foo.bar = JSON.stringify(arguments); foo.baz = JSON.parse(foo.bar); } si la conservation est nécessaire au lieu de la stringification, utilisez l' algorithme de clonage structuré interne . Si des nœuds DOM sont passés, utilisez XMLSerializer comme dans une question non liée . with (new XMLSerializer()) {serializeToString(document.documentElement) }
— Paul Sweatte

7

Comme beaucoup d'autres l'ont souligné, argumentscontient tous les arguments passés à une fonction.

Si vous souhaitez appeler une autre fonction avec les mêmes arguments, utilisez apply

Exemple:

var is_debug = true;
var debug = function() {
  if (is_debug) {
    console.log.apply(console, arguments);
  }
}

debug("message", "another argument")

4

Réponse similaire à Gunnar, avec un exemple plus complet: vous pouvez même renvoyer le tout de manière transparente:

function dumpArguments(...args) {
  for (var i = 0; i < args.length; i++)
    console.log(args[i]);
  return args;
}

dumpArguments("foo", "bar", true, 42, ["yes", "no"], { 'banana': true });

Production:

foo
bar
true
42
["yes","no"]
{"banana":true}

https://codepen.io/fnocke/pen/mmoxOr?editors=0010


3

Oui, si vous n'avez aucune idée du nombre d'arguments possibles au moment de la déclaration de fonction, vous pouvez déclarer la fonction sans paramètres et accéder à toutes les variables par le tableau d'arguments qui est passé au moment de l'appel de la fonction.


2

Dans ES6, vous pouvez faire quelque chose comme ceci:

function foo(...args) 
{
   let [a,b,...c] = args;

   console.log(a,b,c);
}


foo(1, null,"x",true, undefined);


1
Vous pouvez même faire `` `fonction foo (a, b, ... c) {console.log (a, b, c); } ``
— TitouanT

-11

Dans ES6, utilisez Array.from:

function foo()
  {
  foo.bar = Array.from(arguments);
  foo.baz = foo.bar.join();
  }

foo(1,2,3,4,5,6,7);
foo.bar // Array [1, 2, 3, 4, 5, 6, 7]
foo.baz // "1,2,3,4,5,6,7"

Pour le code non ES6, utilisez JSON.stringify et JSON.parse:

function foo()
  {
  foo.bar = JSON.stringify(arguments); 
  foo.baz = JSON.parse(foo.bar); 
  }

/* Atomic Data */
foo(1,2,3,4,5,6,7);
foo.bar // "{"0":1,"1":2,"2":3,"3":4,"4":5,"5":6,"6":7}"
foo.baz // [object Object]

/* Structured Data */
foo({1:2},[3,4],/5,6/,Date())
foo.bar //"{"0":{"1":2},"1":[3,4],"2":{},"3":"Tue Dec 17 2013 16:25:44 GMT-0800 (Pacific Standard Time)"}"
foo.baz // [object Object]

Si la conservation est nécessaire au lieu de la stringification, utilisez l' algorithme de clonage structuré interne .

Si des nœuds DOM sont passés, utilisez XMLSerializer comme dans une question non liée .

with (new XMLSerializer()) {serializeToString(document.documentElement) }

Si vous exécutez en tant que bookmarklet, vous devrez peut-être encapsuler chaque argument de données structurées dans un constructeur d'erreur pour JSON.stringifyfonctionner correctement.

Références


3
Premièrement: cela clonera tous les objets qui seront passés. Deuxièmement: tout ne peut pas être stratifié en JSON. A savoir: fonctions, objets DOM, lesdites dates se transforment en chaînes ...
— John Dvorak

@JanDvorak Pouvez-vous modifier ma réponse avec une fonction qui gère les objets DOM, les fonctions et les dates?
— Paul Sweatte

1
+1, en essayant de passer les arguments pour le rapport d'erreurs sous forme de chaîne, l'objet se termine en tant que chaîne «[Arguments d'objet]» et la journalisation sur la console n'affiche pas les valeurs. Bien qu'il ne semble pas répondre à l'OP, il répond à ma question, merci!
— John
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.