J'ai maintenant vu 2 méthodes pour déterminer si un argument a été passé à une fonction JavaScript. Je me demande si une méthode est meilleure que l'autre ou si l'une est tout simplement mauvaise à 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');
Pour autant que je sache, ils aboutissent tous deux à la même chose, mais je n'ai utilisé que le premier avant en production.
Une autre option mentionnée par Tom :
function Test(argument1, argument2) {
if(argument2 === null) {
argument2 = 'blah';
}
alert(argument2);
}
Selon le commentaire de Juan, il serait préférable de changer la suggestion de Tom pour:
function Test(argument1, argument2) {
if(argument2 === undefined) {
argument2 = 'blah';
}
alert(argument2);
}
javascript
arguments
Darryl Hein
la source
la source
argument2 || 'blah';
résultera en «bla» siargument2
estfalse
(!), Pas simplement s'il n'est pas défini. Siargument2
est un booléen et que la fonction est passéefalse
pour cela, cette ligne retournera 'blah' bien qu'elleargument2
soit correctement définie .argument2
est0
,''
ounull
.Réponses:
Il existe plusieurs façons de vérifier si un argument a été passé à une fonction. En plus des deux que vous avez mentionnés dans votre question (d'origine) - vérifier
arguments.length
ou utiliser l'||
opérateur pour fournir des valeurs par défaut - on peut également vérifier explicitement les argumentsundefined
viaargument2 === undefined
outypeof argument2 === 'undefined'
si l'un est paranoïaque (voir commentaires).Utilisation de l'
||
opérateur est devenu pratique courante - tous les enfants de frais le faire - mais attention: La valeur par défaut est déclenchée si les evalue argument pourfalse
, ce qui signifie qu'il pourrait en fait êtreundefined
,null
,false
,0
,''
(ou toute autre chose dont leBoolean(...)
rendementfalse
).La question est donc de savoir quand utiliser quelle vérification, car ils donnent tous des résultats légèrement différents.
Vérification
arguments.length
présente le comportement «le plus correct», mais il pourrait ne pas être possible s'il y a plus d'un argument facultatif.Le test pour
undefined
est ensuite «meilleur» - il «échoue» uniquement si la fonction est explicitement appelée avec unundefined
valeur, qui, selon toute vraisemblance, doit être traitée de la même manière que l'omission de l'argument.L'utilisation du
||
opérateur peut déclencher l'utilisation de la valeur par défaut même si un argument valide est fourni. D'un autre côté, son comportement pourrait en fait être souhaité.Pour résumer: utilisez-le uniquement si vous savez ce que vous faites!
À mon avis, l'utilisation
||
est également la voie à suivre s'il y a plus d'un argument facultatif et que l'on ne veut pas passer un littéral d'objet comme solution de contournement pour les paramètres nommés.Une autre façon intéressante de fournir des valeurs par défaut en utilisant
arguments.length
est possible en passant par les étiquettes d'une instruction switch:Cela a l'inconvénient que l'intention du programmeur n'est pas (visuellement) évidente et utilise des «nombres magiques»; il est donc probablement sujet aux erreurs.
la source
Si vous utilisez jQuery, une option intéressante (en particulier pour les situations compliquées) consiste à utiliser la méthode extend de jQuery .
Si vous appelez la fonction alors comme ceci:
La variable d'options serait alors:
la source
C'est l'un des rares cas où je trouve le test:
fonctionne très bien et porte la bonne implication syntaxiquement.
(Avec la restriction simultanée que je n'autoriserais pas une valeur nulle légitime pour
argument2
laquelle a une autre signification; mais ce serait vraiment déroutant.)ÉDITER:
Ceci est un très bon exemple de différence stylistique entre les langages peu typés et les types fortement typés; et une option stylistique que javascript offre à la pelle.
Ma préférence personnelle (sans critique pour les autres préférences) est le minimalisme. Moins le code a à dire, tant que je suis cohérent et concis, moins quelqu'un d'autre doit comprendre pour inférer correctement ma signification.
Une implication de cette préférence est que je ne veux pas - ne trouve pas utile de - empiler un tas de tests de dépendance de type. Au lieu de cela, j'essaie de faire en sorte que le code signifie à quoi il ressemble; et tester uniquement pour ce que je devrai vraiment tester.
L'une des aggravations que je trouve dans le code de certains autres peuples est de savoir s'ils s'attendent ou non, dans un contexte plus large, à se heurter réellement aux cas pour lesquels ils testent. Ou s'ils essaient de tester tout ce qui est possible, au cas où ils n'anticipent pas suffisamment le contexte. Ce qui signifie que je dois finir par les retrouver de manière exhaustive dans les deux sens avant de pouvoir refactoriser ou modifier quoi que ce soit en toute confiance. Je pense qu'il y a de fortes chances qu'ils aient mis ces différents tests en place car ils prévoyaient des circonstances où ils seraient nécessaires (et qui ne me sont généralement pas apparents).
(Je considère que c'est un sérieux inconvénient dans la façon dont ces gens utilisent les langages dynamiques. Trop souvent, les gens ne veulent pas abandonner tous les tests statiques et finissent par les simuler.)
J'ai vu cela de façon éclatante en comparant un code ActionScript 3 complet avec un code javascript élégant. L'AS3 peut être 3 ou 4 fois plus gros que les js, et la fiabilité que je soupçonne n'est au moins pas meilleure, simplement en raison du nombre (3-4X) de décisions de codage qui ont été prises.
Comme vous le dites, Shog9, YMMV. :RÉ
la source
Il existe des différences importantes. Configurons quelques cas de test:
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 par défaut , mais tout le premier (comme JS convertira
undefined
,null
,0
et""
dans le booléenfalse
. Et si vous deviez utiliser la méthode de Tom, seul le quatrième test utilisera la valeur par défaut!La méthode que vous choisissez dépend vraiment de votre comportement prévu. Si des valeurs autres que celles
undefined
autorisées sont acceptablesargument2
, alors vous voudrez probablement des variations sur la première; si une valeur non nulle, non nulle et non vide est souhaitée, alors la deuxième méthode est idéale - en effet, elle est souvent utilisée pour éliminer rapidement une si large gamme de valeurs.la source
la source
Dans ES6 (ES2015), vous pouvez utiliser les paramètres par défaut
la source
"default value"
et vérifier si la valeur est bien"default value"
.Je suis désolé, je n'ai pas encore de commentaire, donc pour répondre à la réponse de Tom ... En javascript (undefined! = Null) == false En fait, cette fonction ne fonctionnera pas avec "null", vous devez utiliser "undefined"
la source
Pourquoi ne pas utiliser l'
!!
opérateur? Cet opérateur, placé avant la variable, la transforme en booléen (si j'ai bien compris), donc!!undefined
et!!null
(et même!!NaN
, ce qui peut être assez intéressant) reviendrafalse
.Voici un exemple:
la source
Il peut être pratique d'aborder la détection d'arguments en évoquant votre fonction avec un objet de propriétés facultatives:
la source
Il existe également un moyen délicat de trouver, si un paramètre est passé à une fonction ou non . Jetez un œil à l'exemple ci-dessous:
Cela signifie que si la valeur de
value
n'est pas présente / transmise - définissez-la sur 0.Assez cool hein!
la source
value
est équivalent àfalse
, mettez-le à 0". Il s'agit d'une distinction subtile mais très importante.true
etfalse
sont des valeurs valides, et vous souhaiterez peut-être avoir un troisième comportement lorsque le paramètre n'est pas du tout passé (surtout si la fonction a plus d'un paramètre).Parfois, vous pouvez également vérifier le type, surtout si vous utilisez la fonction comme getter et setter. Le code suivant est ES6 (ne fonctionnera pas dans EcmaScript 5 ou plus ancien):
la source
Parce que les tableaux héritent de
Object.prototype
. Considérez ⇑ pour rendre le monde meilleur.la source
fnCalledFunction (Param1, Param2, window.YourOptionalParameter)
Si la fonction ci-dessus est appelée depuis de nombreux endroits et que vous êtes sûr que les 2 premiers paramètres sont passés de partout, mais que vous n'êtes pas sûr du 3e paramètre, vous pouvez utiliser la fenêtre.
window.param3 gérera s'il n'est pas défini à partir de la méthode de l'appelant.
la source