Est-il possible d'autoriser des vars "illimités" pour une fonction en JavaScript?
Exemple:
load(var1, var2, var3, var4, var5, etc...)
load(var1)
Bien sûr, utilisez simplement l’objet arguments
.
function foo() {
for (var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
Dans la plupart des navigateurs récents, vous pouvez accepter un nombre variable d'arguments avec cette syntaxe:
function my_log(...args) {
// args is an Array
console.log(args);
// You can pass this array as parameters to another function
console.log(...args);
}
Voici un petit exemple:
function foo(x, ...args) {
console.log(x, args, ...args, arguments);
}
foo('a', 'b', 'c', z='d')
=>
a
Array(3) [ "b", "c", "d" ]
b c d
Arguments
0: "a"
1: "b"
2: "c"
3: "d"
length: 4
Documentation et autres exemples ici: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters
Une autre option consiste à transmettre vos arguments dans un objet de contexte.
function load(context)
{
// do whatever with context.name, context.address, etc
}
et l'utiliser comme ça
load({name:'Ken',address:'secret',unused:true})
Cela présente l'avantage que vous pouvez ajouter autant d'arguments nommés que vous le souhaitez et que la fonction peut les utiliser (ou non) à sa guise.
Je suis d’accord avec la réponse de Ken comme étant la plus dynamique et j’aime aller plus loin. Si c'est une fonction que vous appelez plusieurs fois avec des arguments différents, j'utilise le design de Ken, mais j'ajoute ensuite les valeurs par défaut:
function load(context) {
var defaults = {
parameter1: defaultValue1,
parameter2: defaultValue2,
...
};
var context = extend(defaults, context);
// do stuff
}
Ainsi, si vous avez plusieurs paramètres mais que vous n'avez pas nécessairement besoin de les définir à chaque appel de la fonction, vous pouvez simplement spécifier les valeurs par défaut. Pour la méthode extend, vous pouvez utiliser la méthode extend de jQuery ($.extend()
), créer la vôtre ou utiliser les éléments suivants:
function extend() {
for (var i = 1; i < arguments.length; i++)
for (var key in arguments[i])
if (arguments[i].hasOwnProperty(key))
arguments[0][key] = arguments[i][key];
return arguments[0];
}
Cela fusionnera l'objet de contexte avec les valeurs par défaut et remplira toutes les valeurs non définies dans votre objet avec les valeurs par défaut.
Oui, juste comme ça:
function load()
{
var var0 = arguments[0];
var var1 = arguments[1];
}
load(1,2);
Il est préférable d'utiliser la syntaxe du paramètre rest, comme l'a souligné Ramast.
function (a, b, ...args) {}
Je veux juste ajouter quelques propriétés de Nice de l'argument ... args
- C'est un tableau et non un objet comme des arguments. Cela vous permet d'appliquer des fonctions telles que mapper ou trier directement.
- Il n'inclut pas tous les paramètres mais uniquement celui qui en a été transmis. Par exemple. function (a, b, ... args) dans ce cas, args contient l'argument 3 en argument.length
Comme déjà mentionné, vous pouvez utiliser l'objet arguments
pour récupérer un nombre variable de paramètres de fonction.
Si vous voulez appeler une autre fonction avec les mêmes arguments, utilisez apply
. Vous pouvez même ajouter ou supprimer des arguments en convertissant arguments
en un tableau. Par exemple, cette fonction insère du texte avant de se connecter à la console:
log() {
let args = Array.prototype.slice.call(arguments);
args = ['MyObjectName', this.id_].concat(args);
console.log.apply(console, args);
}
Bien que je convienne généralement que l’approche des arguments nommés est utile et souple (à moins que l’ordre ne vous préoccupe, ordre dans lequel les arguments sont les plus faciles), je suis préoccupé par le coût de l’approche de mbeasley (utilisation des valeurs par défaut et étend). Cela représente un coût extrême à prendre pour extraire les valeurs par défaut. Premièrement, les valeurs par défaut sont définies dans la fonction, elles sont donc remplies à chaque appel. Deuxièmement, vous pouvez facilement lire les valeurs nommées et définir les valeurs par défaut en même temps en utilisant ||. Il n'est pas nécessaire de créer et de fusionner un autre nouvel objet pour obtenir ces informations.
function load(context) {
var parameter1 = context.parameter1 || defaultValue1,
parameter2 = context.parameter2 || defaultValue2;
// do stuff
}
C'est à peu près la même quantité de code (peut-être un peu plus), mais cela ne devrait représenter qu'une fraction du coût d'exécution.
Tandis que @roufamatic a montré l'utilisation du mot-clé arguments et que @Ken a montré un excellent exemple d'objet à utiliser, je ne pense pas avoir vraiment abordé ce qui se passait dans ce cas-ci et cela pourrait semer la confusion dans l'esprit des futurs lecteurs ou inculquer une mauvaise pratique/méthode est destiné à prendre une quantité variable d'arguments/paramètres.
function varyArg () {
return arguments[0] + arguments[1];
}
Lorsqu'un autre développeur examine votre code, il est très facile de supposer que cette fonction ne prend pas de paramètres. Surtout si ce développeur n'est pas au courant du mot clé arguments. Pour cette raison, il est judicieux de suivre les directives de style et d’être cohérent. Je vais utiliser Google pour tous les exemples.
Disons explicitement que la même fonction a des paramètres variables:
function varyArg (var_args) {
return arguments[0] + arguments[1];
}
Il peut arriver qu'un objet soit nécessaire, car il s'agit de la seule méthode approuvée et considérée comme la meilleure pratique d'une carte de données. Les tableaux associatifs sont mal vus et découragés.
SIDENOTE: Le mot-clé arguments renvoie en réalité un objet en utilisant des nombres comme clé. L'héritage prototype est également la famille d'objets. Voir la fin de la réponse pour une utilisation correcte du tableau dans JS.
Dans ce cas, nous pouvons également le mentionner explicitement. Remarque: cette convention de dénomination n'est pas fournie par Google mais constitue un exemple de déclaration explicite de type param. Ceci est important si vous souhaitez créer un modèle plus strict dans votre code.
function varyArg (args_obj) {
return args_obj.name+" "+args_obj.weight;
}
varyArg({name: "Brian", weight: 150});
Cela dépend des besoins de votre fonction et de votre programme. Si, par exemple, vous cherchez simplement à renvoyer une base de valeurs sur un processus itératif pour tous les arguments passés, restez certainement avec le mot clé arguments. Si vous avez besoin de définir vos arguments et de mapper les données, la méthode objet est la solution. Regardons deux exemples et ensuite nous avons terminé!
function sumOfAll (var_args) {
return arguments.reduce(function(a, b) {
return a + b;
}, 0);
}
sumOfAll(1,2,3); // returns 6
function myObjArgs(args_obj) {
// MAKE SURE ARGUMENT IS AN OBJECT OR ELSE RETURN
if (typeof args_obj !== "object") {
return "Arguments passed must be in object form!";
}
return "Hello "+args_obj.name+" I see you're "+args_obj.age+" years old.";
}
myObjArgs({name: "Brian", age: 31}); // returns 'Hello Brian I see you're 31 years old
Comme mentionné en haut de la réponse, le mot clé arguments renvoie en fait un objet. Pour cette raison, toute méthode que vous souhaitez utiliser pour un tableau devra être appelée. Un exemple de ceci:
Array.prototype.map.call(arguments, function (val, idx, arr) {});
Pour éviter cela, utilisez le paramètre rest:
function varyArgArr (...var_args) {
return var_args.sort();
}
varyArgArr(5,1,3); // returns 1, 3, 5
Utilisez l’objet arguments
à l’intérieur de la fonction pour avoir accès à tous les arguments transmis.
Sachez que le fait de transmettre un objet avec les propriétés nommées, comme suggéré par Ken, ajoute le coût de l'allocation et de la libération de l'objet temporaire à chaque appel. Passer les arguments normaux par valeur ou par référence sera généralement le plus efficace. Pour de nombreuses applications, les performances ne sont pas critiques mais peuvent l'être pour certaines.