web-dev-qa-db-fra.com

JavaScript: Les paramètres "infinis" pour la fonction?

Chrome, quand je tape console.log dans celui ci-dessous:

console.log("A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter");

... Cela l'imprime correctement, sans erreurs ni avertissements. J'ai ajouté plus de paramètres, mais cela l'imprime toujours correctement.

console.log("A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter");

Comment puis-je avoir une fonction de paramètre "infini" comme celle-là?

38
user824294

Les fonctions peuvent accéder à un objet de type tableau appelé arguments qui contient tous les arguments qu'ils ont reçus

function print_my_arguments(/**/){
    var args = arguments;
    for(var i=0; i<args.length; i++){
        console.log(args[i]);
    }
};

Et vous pouvez faire la conversion opposée (appelez une fonction donnée une liste d'arguments) avec la méthode Appliquer:

// These are equivalent:
print_my_arguments(1,2,3);
print_my_arguments.apply(null, [1,2,3]);

// The first parameter to `apply` is the `this`.
// It is used when the function is a method.
foo.bar(1,2,3);
var f = foo.bar; f.apply(foo, [1,2,3]);

Quelques points importants à noter:

  1. arguments n'est pas un tableau réel et il n'a aucune des méthodes de tableau habituelles (Slice, Join, etc.). Vous pouvez le convertir en une matrice avec la ligne suivante:

    var args = Array.prototype.slice.call(arguments);
    
  2. Slice est également utile si vous voulez que votre réseau ne contienne que les arguments non nommés reçus:

    function foo(first_arg, second_arg /**/){
        var variadic_args = Array.prototype.slice.call(arguments, 2);
    }
    
  3. Tous les navigateurs ne peuvent pas gérer un nombre de paramètres de fonction arbitrairement volumineux. La dernière fois que j'ai testé cela, dans Chrome et IE il y avait un impertiniverflow après quelque 200 000 arguments. Si votre fonction peut recevoir un grand nombre d'arguments arbitrairement, envisagez de conserver tous ces arguments dans une matrice régulière.

  4. Ceux /**/ Les commentaires figurant dans les arguments listes de mes exemples ne sont pas obligatoires. Ils sont juste un codage d'une convention que j'utilise pour marquer mes fonctions variadiques et les différencier des fonctions régulières.

    // A quick glance would suggest that this function receives no
    // parameters but actually it is a variadic function that gets
    // its parameters via the `arguments` object.
    function foo(){
        console.log(arguments.length);
    }
    
55
hugomg

La manière moderne de faire cela utilise paramètres de repos :

function printArguments(...args) {
  args.forEach((arg, index) => {
    console.log(`Argument ${index}:`, arg);
  });
}

printArguments('hello', true, new Date());

En utilisant le ...args Syntaxe, tous les paramètres sont enregistrés dans une matrice nommée args.

À l'exception de l'Explorateur Internet, tous les navigateurs expédient déjà cette fonctionnalité dans leur version la plus récente.

Fiddle: https://jsfiddle.net/lbf0stst/

8
Felix Edelmann

Vous pouvez utiliser le tableau Arguments: jsfiddle.net/kunj2/

function foo() {
    for (var i = 0; i < arguments.length; i++) {
        document.body.innerHTML += arguments[i];
    }
}


foo("There ", "are ", "as ", "much ", "arguments ", "as ", "you ", "want.");
0
DynasteN