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.

Thomas Eding
la source
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

Luc
la source
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]); 
}
Gunnar Forsgren - Mobimation
la source
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

iConnor
la source
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).

Iman Mohamadi
la source
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")
Lasse Skindstad Ebert
la source
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

Frank Nocke
la source
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.

Rubi saini
la source
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);

Kamil Kiełczewski
la source
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

Paul Sweatte
la source
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