92 votes

Les opérateurs Splat en JavaScript, équivalents aux *args et **kwargs en Python ?

J'utilise beaucoup Python, et je suis en train d'apprendre rapidement JavaScript en ce moment (ou devrais-je dire réapprendre). Je voulais donc demander quel est l'équivalent de *args et **kwargs en JavaScript ?

55voto

torazaburo Points 6335

L'idiome le plus proche pour *args serait

function func (a, b /*, *args*/) {
    var star_args = Array.prototype.slice.call (arguments, func.length);
    /* now star_args[0] is the first undeclared argument */
}

en profitant du fait que Function.length est le nombre d'arguments donnés dans la définition de la fonction.

Vous pourriez emballer ceci dans une petite routine d'aide comme

function get_star_args (func, args) {
    return Array.prototype.slice.call (args, func.length);
}

et ensuite faire

function func (a, b /*, *args*/) {
    var star_args = get_star_args (func, arguments);
    /* now star_args[0] is the first undeclared argument */
}

Si vous êtes d'humeur à utiliser du sucre syntaxique, écrivez une fonction qui transforme une fonction en une autre qui est appelée avec des arguments obligatoires et facultatifs, et qui transmet les arguments obligatoires, avec tout argument facultatif supplémentaire sous forme de tableau en position finale :

function argsify(fn){
    return function(){
        var args_in   = Array.prototype.slice.call (arguments); //args called with
        var required  = args_in.slice (0,fn.length-1);     //take first n   
        var optional  = args_in.slice (fn.length-1);       //take remaining optional
        var args_out  = required;                          //args to call with
        args_out.push (optional);                          //with optionals as array
        return fn.apply (0, args_out);
    };
}

Utilisez-le comme suit :

// original function
function myfunc (a, b, star_args) {
     console.log (a, b, star_args[0]); // will display 1, 2, 3
}

// argsify it
var argsified_myfunc = argsify (myfunc);

// call argsified function
argsified_myfunc (1, 2, 3);

Mais vous pouvez aussi vous passer de tout ce charabia si vous êtes prêt à demander à l'appelant de passer les arguments optionnels sous forme de tableau pour commencer :

myfunc (1, 2, [3]);

Il n'y a pas vraiment de solution analogue pour **kwargs puisque JS n'a pas d'arguments sous forme de mots-clés. Au lieu de cela, il suffit de demander à l'appelant de passer les arguments optionnels dans un objet :

function myfunc (a, b, starstar_kwargs) {
    console.log (a, b, starstar_kwargs.x);
}

myfunc (1, 2, {x:3});

Mise à jour de l'ES6

Pour être complet, permettez-moi d'ajouter que l'ES6 résout ce problème avec la fonctionnalité de paramètre de repos. Voir Javascript - signification de "...".

51voto

Helio Santos Points 3307

ES6 a ajouté un opérateur d'étalement à JavaScript.

function choose(choice, ...availableChoices) {
    return availableChoices[choice];
}

choose(2, "one", "two", "three", "four");
// returns "three"

18voto

lukewendling Points 959

J'ai trouvé une bonne solution ici : http://readystate4.com/2008/08/17/javascript-argument-unpacking-converting-an-array-into-a-list-of-arguments/

En gros, utilisez function.apply(obj, [args]) au lieu de function.call . apply prend un tableau comme deuxième argument et le "splate" pour vous.

8voto

NPE Points 169956

L'équivalent le plus proche est le arguments pseudo-réseau .

2voto

Cameron Martin Points 826

ECMAScript 6 aura paramètres de repos qui font la même chose que l'opérateur splat.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X