web-dev-qa-db-fra.com

Est-il possible d'envoyer un nombre variable d'arguments à une fonction JavaScript?

Est-il possible d'envoyer un nombre variable d'arguments à une fonction JavaScript, à partir d'un tableau? 

var arr = ['a','b','c']

var func = function()
{
    // debug 
    alert(arguments.length);
    //
    for(arg in arguments)
        alert(arg);
}

func('a','b','c','d'); // prints 4 which is what I want, then 'a','b','c','d'
func(arr); // prints 1, then 'Array'

J'ai récemment écrit beaucoup de Python et c'est un modèle merveilleux pour pouvoir accepter des varargs et les envoyer. par exemple.

def func(*args):
   print len(args)
   for i in args:
       print i

func('a','b','c','d'); // prints 4 which is what I want, then 'a','b','c','d'
func(*arr) // prints 4 which is what I want, then 'a','b','c','d'

Est-il possible en JavaScript d'envoyer un tableau à traiter comme le tableau des arguments? 

147
Fire Crow

Utilisez appliquez :

var arr = ['a','b','c'];

var func = function() {
  alert(arguments.length);

  for(var i = 0; i < arguments.length; i++) {
    alert(arguments[i]);
  }

};

func.apply(null, arr);

Notez que null est utilisé comme premier argument de apply, ce qui définira le mot clé this sur l'objet Global (fenêtre) dans func.

Notez également que l'objet arguments n'est pas vraiment un tableau, vous pouvez le convertir de la manière suivante:

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

Et peut-être vous est-il utile que vous sachiez combien d'arguments attend une fonction:

var test = function (one, two, three) {}; 
test.length == 3;

Mais de toute façon, vous pouvez passer un nombre arbitraire d'arguments ...

168
CMS

Vous pouvez réellement transmettre autant de valeurs que vous le souhaitez à n'importe quelle fonction javascript. Les paramètres explicitement nommés obtiendront les premières valeurs, mais TOUS les paramètres seront stockés dans le tableau des arguments.

Pour passer le tableau d'arguments sous une forme "décompressée", vous pouvez utiliser appliquer, comme suit (c.f. Javascript fonctionnel ):

var otherFunc = function() {
   alert(arguments.length); // Outputs: 10
}

var myFunc = function() {
  alert(arguments.length); // Outputs: 10
  otherFunc.apply(this, arguments);
}
myFunc(1,2,3,4,5,6,7,8,9,10);
68
danben

Les opérateurs splat et spread font partie de ES6, la prochaine version prévue de Javascript. Jusqu'à présent, seul Firefox les prend en charge. Ce code fonctionne dans FF16 +:

var arr = ['quick', 'brown', 'lazy'];

var sprintf = function(str, ...args)
{
    for (arg of args) {
        str = str.replace(/%s/, arg);
    }
    return str;
}

sprintf.apply(null, ['The %s %s fox jumps over the %s dog.', ...arr]);
sprintf('The %s %s fox jumps over the %s dog.', 'slow', 'red', 'sleeping');

Notez la syntaxe awkard pour la propagation. La syntaxe habituelle de sprintf('The %s %s fox jumps over the %s dog.', ...arr); est pas encore supportée . Vous pouvez trouver un tableau de compatibilité ES6 ici .

Notez également l'utilisation de for...of , un autre ajout à ES6. Utiliser for...in pour les tableaux est une mauvaise idée .

21
Tgr

Il existe deux méthodes à partir de ES2015.

L'objet arguments

Cet objet est intégré à des fonctions et fait référence, de manière appropriée, aux arguments d’une fonction. Techniquement, ce n'est pas un tableau, donc les opérations de tableau typiques ne fonctionneront pas dessus. La méthode suggérée consiste à utiliser Array.from ou l'opérateur spread pour créer un tableau à partir de celui-ci.

J'ai vu d'autres réponses mentionner l'utilisation de slice. Ne fais pas ça. Cela empêche les optimisations (source: MDN ).

Array.from(arguments)
[...arguments]

Cependant, je dirais que arguments est problématique car il cache ce qu'une fonction accepte en entrée. Une fonction arguments s'écrit généralement comme ceci:

function mean(){
    let args = [...arguments];
    return args.reduce((a,b)=>a+b) / args.length;
}

Parfois, l'en-tête de la fonction est écrit comme suit pour documenter les arguments de la manière d'un C:

function mean(/* ... */){ ... }

Mais c'est rare.

Quant à savoir pourquoi c'est problématique, prenons C, par exemple. C est rétrocompatible avec un ancien dialecte pré-ANSI du langage appelé K & R. K & R C permet aux prototypes de fonctions d’avoir une liste d’arguments vide.

int myFunction();
/* This function accepts unspecified parameters */

ANSI C fournit une installation pour varargs (...) et void pour spécifier une liste d'arguments vide.

int myFunction(void);
/* This function accepts no parameters */

De nombreuses personnes déclarent par inadvertance des fonctions avec une liste d'arguments unspecified (int myfunction();), lorsqu'elles s'attendent à ce que la fonction prenne zéro argument. C'est techniquement un bug car la fonction will accepte les arguments. N'importe quel nombre d'entre eux.

Une fonction varargs propre en C prend la forme:

int myFunction(int nargs, ...);

Et JavaScript a effectivement quelque chose de similaire à cela.

Spread Operator / Paramètres de repos

Je vous ai déjà montré l'opérateur de propagation, en fait.

...name

Il est assez polyvalent et peut également être utilisé dans la liste d'arguments d'une fonction ("paramètres de repos") pour spécifier des variables de manière bien documentée:

function mean(...args){
    return args.reduce((a,b)=>a+b) / args.length;
}

Ou comme une expression lambda:

((...args)=>args.reduce((a,b)=>a+b) / args.length)(1,2,3,4,5); // 3

Je préfère de loin l'opérateur de propagation. C'est propre et auto-documentant.

8
Braden Best

La fonction apply prend deux arguments; l'objet this sera lié à, et les arguments, représentés avec un tableau.

some_func = function (a, b) { return b }
some_func.apply(obj, ["arguments", "are", "here"])
// "are"
7
August Lilleaas

C'est ce qu'on appelle l'opérateur splat. Vous pouvez le faire en JavaScript en utilisant apply:

var arr = ['a','b','c','d'];
var func = function() {
    // debug 
    console.log(arguments.length);
    console.log(arguments);
}
func('a','b','c','d'); // prints 4 which is what I want, then 'a','b','c','d'
func(arr); // prints 1, then 'Array'
func.apply(null, arr); 
5
Chandra Patni

Avec ES6, vous pouvez utiliser paramètres de repos pour varagrs. Cela prend la liste des arguments et la convertit en tableau.

function logArgs(...args) {
    console.log(args.length)
    for(let arg of args) {
        console.log(arg)
    }
}
4
theres.yer.problem

Ceci est un exemple de programme permettant de calculer la somme des nombres entiers pour les arguments variables et les tableaux sur les nombres entiers. J'espère que cela t'aides.

var CalculateSum = function(){
    calculateSumService.apply( null, arguments );
}

var calculateSumService = function(){
    var sum = 0;

    if( arguments.length === 1){
        var args = arguments[0];

        for(var i = 0;i<args.length; i++){
           sum += args[i]; 
        }
    }else{
        for(var i = 0;i<arguments.length; i++){
           sum += arguments[i]; 
        }        
    }

     alert(sum);

}


//Sample method call

// CalculateSum(10,20,30);         

// CalculateSum([10,20,30,40,50]);

// CalculateSum(10,20);
2
streak
(function(window) {
  var proxied = window.alert;
  window.alert = function() {
    return proxied.apply(window, arguments);
  };
}(this));

alert(13, 37);
2
yckart

Pour ceux qui ont été redirigés ici à partir de Passage d'un nombre variable d'arguments d'une fonction à une autre (qui devrait ne pas être marqué comme duplicata de cette question):

Si vous essayez de passer un nombre variable d'arguments d'une fonction à une autre, depuis JavaScript 1.8.5, vous pouvez simplement appeler apply() sur la deuxième fonction et passer le paramètre arguments:

var caller = function()
{
    callee.apply( null, arguments );
}

var callee = function()
{
    alert( arguments.length );
}

caller( "Hello", "World!", 88 ); // Shows "3".

Remarque: Le premier argument est le paramètre this à utiliser. Passer null appellera la fonction à partir du contexte global, c’est-à-dire en tant que fonction globale au lieu de la méthode d’un objet.

Selon ce document , la spécification ECMAScript 5 a redéfini la méthode apply() pour prendre tout "objet générique semblable à un tableau", au lieu d'un tableau strictement. Ainsi, vous pouvez directement passer la liste arguments dans la deuxième fonction.

Testé dans Chrome 28.0, Safari 6.0.5 et IE 10. Essayez-le avec ce JSFiddle .

1
andrewtc

Oui, vous pouvez passer la variable non. des arguments à une fonction. Vous pouvez utiliser apply pour y parvenir.

Par exemple.:

var arr = ["Hi","How","are","you"];

function applyTest(){
    var arg = arguments.length;
    console.log(arg);
}

applyTest.apply(null,arr);
0
Abhijit

Voulez-vous que votre fonction réagisse à un argument de tableau ou à des arguments variables? Si ce dernier, essayez:

var func = function(...rest) {
  alert(rest.length);

  // In JS, don't use for..in with arrays
  // use for..of that consumes array's pre-defined iterator
  // or a more functional approach
  rest.forEach((v) => console.log(v));
};

Mais si vous souhaitez gérer un argument de tableau

var fn = function(arr) {
  alert(arr.length);

  for(var i of arr) {
    console.log(i);
  }
};
0
Dev Yego