128 votes

Gestion des paramètres facultatifs en javascript

J'ai une statique de la fonction javascript qui peut prendre 1, 2 ou 3 paramètres:

function getData(id, parameters, callback) //parameters (associative array) and callback (function) are optional

Je sais que je peux toujours tester si un paramètre n'est pas défini, mais comment savoir si ce qui a été transmis a été le paramètre ou la fonction de rappel?

Quelle est la meilleure façon de le faire?


Des exemples de ce qui pourrait être transmis à:

1:

getData('offers');

2:

var array = new Array();
array['type']='lalal';
getData('offers',array);

3:

var foo = function (){...}
getData('offers',foo);

4:

getData('offers',array,foo);

162voto

CMS Points 315406

Vous pouvez savoir combien d' arguments ont été transférés à votre fonction et vous pouvez vérifier si votre deuxième argument est une fonction ou pas:

function getData (id, parameters, callback) {
  if (arguments.length == 2) { // if only two arguments were supplied
    if (Object.prototype.toString.call(parameters) == "[object Function]") {
      callback = parameters; 
    }
  }
  //...
}

Vous pouvez également utiliser l'objet arguments de cette façon:

function getData (/*id, parameters, callback*/) {
  var id = arguments[0], parameters, callback;

  if (arguments.length == 2) { // only two arguments supplied
    if (Object.prototype.toString.call(arguments[1]) == "[object Function]") {
      callback = arguments[1]; // if is a function, set as 'callback'
    } else {
      parameters = arguments[1]; // if not a function, set as 'parameters'
    }
  } else if (arguments.length == 3) { // three arguments supplied
      parameters = arguments[1];
      callback = arguments[2];
  }
  //...
}

Si vous êtes intéressés, donner un coup d'oeil à cet article par John Resig, à propos d'une technique pour simuler la surcharge de méthode sur le JavaScript.

75voto

meder Points 81864

Er - cela implique que vous appelez votre fonction avec des arguments qui ne sont pas dans le bon ordre... je ne recommanderais pas.

Je recommanderais plutôt que de nourrir un objet à votre fonction comme ceci:

function getData( props ) {
    props = props || {};
    props.params = props.params || {};
    props.id = props.id || 1;
    props.callback = props.callback || function(){};
    alert( props.callback )
};

getData( {
    id: 3,
    callback: function(){ alert('hi'); }
} );

Avantages:

  • vous n'avez pas de compte pour l'argument de l'ordre
  • vous n'avez pas à faire de ce type de vérification
  • il est plus facile de définir des valeurs par défaut, car aucune vérification n'est nécessaire
  • moins de maux de tête. imaginez si vous avez ajouté un quatrième argument, vous devez mettre à jour votre type de vérification à chaque fois, et que si la quatrième ou consécutifs, sont également des fonctions?

Inconvénients:

  • temps de refactoriser le code

Si vous n'avez pas le choix, vous pouvez utiliser une fonction pour détecter si un objet est en effet une fonction ( voir le dernier exemple ).

Remarque: Ce est la bonne façon de détecter une fonction:

function isFunction(obj) {
    return Object.prototype.toString.call(obj) === "[object Function]";
}

isFunction( function(){} )

2voto

James Black Points 26183

Donc, utiliser l'opérateur typeof pour déterminer si le second paramètre est un Tableau ou une fonction.

Cela peut donner quelques suggestions: http://www.planetpdf.com/developer/article.asp?ContentID=testing_for_object_types_in_ja

Je ne suis pas certain si c'est un travail ou d'un travail, donc je ne veux pas vous donner la réponse pour le moment, mais la typeof vous aidera à déterminer.

2voto

Kamil Szot Points 4521

Vous devez vérifier le type de paramètres reçus. Peut-être devriez-vous utiliser arguments array car second paramètre peut parfois être «paramètres» et parfois «callback» et les nommer peuvent être trompeurs.

2voto

zVictor Points 1501

Je vous recommande d'utiliser ArgueJS .

Vous pouvez simplement taper votre fonction de cette façon:

 function getData(){
  arguments = __({id: String, parameters: [Object], callback: [Function]})

  // and now access your arguments by arguments.id,
  //          arguments.parameters and arguments.callback
}
 

J'ai considéré par vos exemples que vous voulez que votre paramètre id soit une chaîne, non? Maintenant, getData exige un String id et accepte les options Object parameters et Function callback . Tous les cas d'utilisation que vous avez publiés fonctionneront comme prévu.

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