247 votes

La meilleure façon de déterminer si un argument n’est pas envoyé à la fonction JavaScript

J'ai maintenant vu 2 méthodes pour déterminer si un argument a été transmis à la fonction JavaScript. Je me demandais si une méthode est meilleure que l'autre ou si l'une est tout simplement mauvais à utiliser?

 function Test(argument1, argument2) {
      if (Test.arguments.length == 1) argument2 = 'blah';

      alert(argument2);
 }

 Test('test');

Ou

 function Test(argument1, argument2) {
      argument2 = argument2 || 'blah';

      alert(argument2);
 }

 Test('test');

Aussi loin que je peux dire, elles résultent de la même chose, mais je ne l'ai utilisé la première avant dans la production.

Une autre Option, comme mentionné par Tom:

function Test(argument1, argument2) {
    if(argument2 === null) {
        argument2 = 'blah';
    }

    alert(argument2);
}

Comme par Juan commentaire, il serait préférable de changer de Tom suggestion:

function Test(argument1, argument2) {
    if(argument2 === undefined) {
        argument2 = 'blah';
    }

    alert(argument2);
}

287voto

Christoph Points 64389

Il existe plusieurs façons de vérifier si un argument est passé à une fonction. En plus des deux que vous avez mentionné dans votre (original) question - vérification de l' arguments.length ou à l'aide de l' || de l'opérateur de fournir des valeurs par défaut - on peut aussi explicitement vérifier les arguments pour undefined par argument2 === undefined ou typeof argument2 === 'undefined' si l'on est paranoïaque (voir les commentaires).

À l'aide de l' || opérateur est devenu un standard de pratique - tous les cool kids à le faire - mais attention: La valeur par défaut sera déclenchée si l'argument évalue false, ce qui signifie qu'il pourrait en fait être undefined, null, false, 0, '' (ou n'importe quoi d'autre pour qui Boolean(...) retours false).

Donc, la question est de savoir quand utiliser les vérifier, car elles conduisent toutes à des résultats légèrement différents.

Vérification de l' arguments.length des expositions le plus correct " de comportement, mais il pourrait ne pas être possible si il n'y a plus d'un argument optionnel.

Le test pour undefined est à côté de la 'meilleure' - il échoue seulement si la fonction est appelée explicitement avec un undefined de la valeur, qui, selon toute probabilité doivent être traités de la même manière que l'omission de l'argument.

L'utilisation de l' || opérateur pourrait déclencher de l'utilisation de la valeur par défaut, même si un argument valide est fourni. D'autre part, son comportement pourrait en fait être désiré.

Pour résumer: à n'utiliser que si vous savez ce que vous faites!

À mon avis, à l'aide de || est également la voie à suivre si il y a plus d'un argument optionnel et l'on ne veut pas passer un objet littéral comme une solution de contournement pour les paramètres nommés.

Une autre belle façon de fournir des valeurs par défaut à l'aide de arguments.length est possible en tombant à travers les étiquettes d'une instruction switch:

function test(requiredArg, optionalArg1, optionalArg2, optionalArg3) {
    switch(arguments.length) {
        case 1: optionalArg1 = 'default1';
        case 2: optionalArg2 = 'default2';
        case 3: optionalArg3 = 'default3';
        case 4: break;
        default: throw new Error('illegal argument count')
    }
    // do stuff
}

Cela a l'inconvénient que le programmeur a l'intention n'est pas (visuellement) évident, et utilise des "nombres magiques"; c'est donc peut-être sujettes à erreur.

17voto

Greg Tatum Points 325

Si vous utilisez jQuery, une option qui est agréable (surtout pour les situations compliquées) est d’utiliser jQuery étendre méthode.

Si vous appelez la fonction puis comme ceci :

La variable options serait alors :

16voto

le dorfier Points 27267

C'est l'un des rares cas où je trouve le test:

if(! argument2) {  

}

fonctionne très bien et porte l'implication correcte du point de vue syntaxique.

(Avec les simultanée de restriction que je ne voudrais pas laisser une légitime valeur null pour argument2 qui a une autre signification, mais qui serait vraiment à confusion.)

EDIT:

C'est un très bon exemple d'une différence stylistique entre faiblement typé et fortement typé langues; et d'un choix d'option javascript offre à la pelle.

Ma préférence personnelle (avec aucune critique destinés à d'autres préférences) est le minimalisme. Le moins le code est-à-dire, tant que je suis cohérent et concis, le moins que quelqu'un d'autre a comprendre pour déduire correctement mon sens.

L'une des conséquences de cette préférence est que je ne veux pas - ne trouve pas ça utile à accumuler un tas de type de dépendance de tests. Au lieu de cela, j'ai essayer de faire le code dire à quoi il ressemble, il signifie; et de tester seulement pour ce dont j'ai réellement besoin de tester pour.

L'un des aggravations je trouve dans certains autres peuples code est besoin de savoir si oui ou non ils s'attendre, dans un contexte plus large, à exécuter sur les cas, ils sont tests pour. Ou si ils sont en train de tester, pour tout ce qui est possible, à l'occasion de ne pas anticiper le contexte tout à fait satisfaisant. Ce qui signifie que je finis par avoir besoin de retracer de manière exhaustive dans les deux directions avant je peux en toute confiance refactoriser ou modifier quoi que ce soit. Je suppose qu'il ya une bonne chance qu'ils pourraient avoir à mettre ces différents tests sont en place, car ils prévoyaient le cas où elles seraient nécessaires (et qui ne sont pas habituellement évident pour moi).

(Je pense qu'un grave inconvénient dans la façon dont ces gens utilisent des langages dynamiques. Trop souvent, les gens ne veulent pas renoncer à tous les essais statiques, et à la fin de faire semblant.)

J'ai vu cette plus évidente dans la comparaison globale de code ActionScript 3 avec élégant du code javascript. L'AS3 peut être 3 ou 4 fois la masse de la js, et la fiabilité, je pense est au moins pas de meilleur, tout simplement parce que le nombre (3-4X) de codage des décisions qui ont été prises.

Comme vous le dites, Shog9, YMMV. :D

7voto

Shog9 Points 82052

Il existe des différences importantes. Prenons quelques cas de test:

var unused; // value will be undefined
Test("test1", "some value");
Test("test2");
Test("test3", unused);
Test("test4", null);
Test("test5", 0);
Test("test6", "");

Avec la première méthode que vous décrivez, seul le deuxième test utilisera la valeur par défaut. La deuxième méthode sera, par défaut, tous les mais la première (JS va convertir undefined, null, 0, et "" dans le booléen false. Et si vous étiez à utiliser Tom de la méthode, seul le quatrième test utilisera la valeur par défaut!

La méthode que vous choisissez dépend de votre comportement voulu. Si les valeurs autres que d' undefined sont possibles pour argument2, alors vous voudrez probablement une certaine variation sur la première; si elle est non nulle, non-nulle, la valeur non vide est souhaitée, la deuxième méthode est idéale, en effet, il est souvent utilisé pour éliminer rapidement un large éventail de valeurs.

7voto

Lamy Points 1127

URL = url === indéfini ? Location.href : url ;

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