booléen dans une instruction if

144

Aujourd'hui, j'ai une remarque sur le code en considérant la façon dont je vérifie si une variable est vraie ou fausse dans un devoir scolaire.

Le code que j'avais écrit était quelque chose comme ceci:

var booleanValue = true;

function someFunction(){
    if(booleanValue === true){
        return "something";
    }
}

Ils ont dit qu'il était préférable / plus soigné de l'écrire comme ceci:

var booleanValue = true;

function someFunction(){
    if(booleanValue){
        return "something";
    }
}

La remarque que j'ai eue à propos de la partie "=== true" était qu'elle n'était pas nécessaire et pouvait créer de la confusion.

Cependant mon idée est qu'il vaut mieux vérifier si la variable est un booléen ou non, d'autant plus que Javascript est un langage de type lâche.

Dans le deuxième exemple, une chaîne renverrait également "quelque chose";

Donc ma question; Est-il plus judicieux de perdre la partie "=== true" à l'avenir, ou est-ce une bonne pratique de vérifier également le type de la variable.

Edit: Dans mon code "réel", le booléen représente si une image a été supprimée ou non, donc la seule valeur que boolValue devrait avoir est true ou false.

0 et 1 par exemple ne devraient pas être dans cette variable.

DirkZz
la source
4
il est lisible et une bonne pratique à utiliser ===
Piyas De
2
+1 pour === true. Évite la confusion !!
gashu
1
@gashu Considère que la valeur est [0] === truefalse.
RestingRobot
1
@Jlange ne devrait pas? Veuillez expliquer
gashu
Ce que je voulais dire par là, c'est que si vous vouliez simplement vérifier l'existence d'une "vérité", cette déclaration échouerait, même si elle devrait être évaluée à vrai ([0] est évalué à vrai mais pas sans conversion de type). Cela dépend vraiment de ce que vous essayez d'accomplir avec votre déclaration. À utiliser === truelorsque vous devez vous assurer que la condition est exactement égale à true.
RestingRobot

Réponses:

222

Tout d'abord, les faits:

if (booleanValue)

Satisfaire l' ifinstruction pour toute valeur de vérité d' booleanValueinclusion true, tout nombre non nul, toute valeur de chaîne non vide, toute référence d'objet ou de tableau, etc.

D'autre part:

if (booleanValue === true)

Cela ne satisfera la ifcondition que si booleanValueest exactement égal à true. Aucune autre valeur de vérité ne le satisfera.

D'un autre côté, si vous faites ceci:

if (someVar == true)

Ensuite, ce que Javascript fera est de taper coerce truepour correspondre au type de someVar, puis de comparer les deux variables. Il existe de nombreuses situations où ce n'est probablement pas ce que l'on aurait voulu. Pour cette raison, dans la plupart des cas, vous voulez éviter ==car il existe un ensemble assez long de règles sur la façon dont Javascript va taper forcer deux choses à être du même type et à moins que vous ne compreniez toutes ces règles et que vous puissiez anticiper tout ce que l'interpréteur JS pourrait faire quand étant donné deux types différents (que la plupart des développeurs JS ne peuvent pas), vous voudrez probablement éviter ==complètement.

Pour illustrer à quel point cela peut être déroutant:

var x;

x = 0;
console.log(x == true);   // false, as expected
console.log(x == false);  // true as expected

x = 1;
console.log(x == true);   // true, as expected
console.log(x == false);  // false as expected

x = 2;
console.log(x == true);   // false, ??
console.log(x == false);  // false 

Pour la valeur 2, vous penseriez qu'il 2s'agit d'une valeur de vérité, donc elle se comparerait favorablement à true, mais ce n'est pas ainsi que fonctionne la coercition de type. Il convertit la valeur de la main droite pour qu'elle corresponde au type de la valeur de la main gauche afin de la convertir trueen nombre 1afin de comparer 2 == 1ce qui n'est certainement pas ce que vous vouliez probablement.

Alors, méfiez-vous de l'acheteur. Il est probablement préférable d'éviter ==dans presque tous les cas, à moins que vous ne connaissiez explicitement les types que vous comparerez et que vous sachiez comment fonctionnent tous les algorithmes de coercition de types possibles.


Donc, cela dépend vraiment des valeurs attendues pour booleanValueet de la façon dont vous voulez que le code fonctionne. Si vous savez à l'avance qu'il n'aura jamais qu'une valeur trueou false, comparez-le explicitement avec

if (booleanValue === true)

est juste un code supplémentaire et inutile et

if (booleanValue)

est plus compact et sans doute plus propre / meilleur.

Si, en revanche, vous ne savez pas ce que cela booleanValuepourrait être et que vous souhaitez tester s'il est vraiment défini sur truesans aucune autre conversion automatique de type autorisée, alors

if (booleanValue === true)

n'est pas seulement une bonne idée, mais obligatoire.


Par exemple, si vous regardez l'implémentation de .on()dans jQuery, il a une valeur de retour facultative. Si le rappel revient false, jQuery arrêtera automatiquement la propagation de l'événement. Dans ce cas précis, puisque jQuery veut arrêter SEULEMENT la propagation s'il a falseété renvoyé, ils vérifient la valeur de retour explicite === falseparce qu'ils ne veulent pas undefinedou 0ou ""ou quoi que ce soit d'autre qui sera automatiquement converti en faux pour satisfaire également la comparaison.

Par exemple, voici le code de rappel de gestion des événements jQuery:

ret = ( specialHandle || handleObj.handler ).apply( matched.elem, args );

if ( ret !== undefined ) {
     event.result = ret;
     if ( ret === false ) {
         event.preventDefault();
         event.stopPropagation();
     }
 }

Vous pouvez voir que jQuery recherche explicitement ret === false.

Mais, il y a aussi de nombreux autres endroits dans le code jQuery où une vérification plus simple est appropriée étant donné le désir du code. Par exemple:

// The DOM ready check for Internet Explorer
function doScrollCheck() {
    if ( jQuery.isReady ) {
        return;
    }
    ...
jfriend00
la source
Je réfléchis à cette question depuis un certain temps, mais je n'ai pas eu la chance de trouver quelqu'un à poser. J'apprécierais si vous pouviez jeter un coup d'œil. stackoverflow.com/questions/32615466/…
mmm
Cette réponse n'est pas tout à fait correcte. «x == true» ne sera pas vrai pour les nombres non nuls.
Teemoh
@Teemoh - Je ne comprends pas votre commentaire. Voir jsfiddle.net/jfriend00/89h8d8tm .
jfriend00
1
Je veux juste dire que «si (x)» n'est pas la même chose que «si (x == vrai)», comme vous l'avez écrit dans le premier paragraphe de votre réponse. 'if (x)' convertira explicitement 'x' en sa représentation booléenne. 'if (x == true)' utilisera l'algorithme de comparaison abstraite EcmaScript. Vous avez écrit que «if (x == true)» sera vrai pour tout nombre non nul ou chaîne non vide ou tout objet. C'est tout simplement faux. Si je lance votre exemple avec 2 au lieu de 1, cela ne fonctionnera pas.
Teemoh
2
@Teemoh - Je comprends votre point de vue. Réponse corrigée et clarifiée et j'ai ajouté une section sur la coercition de type avec un exemple qui montre comment il peut faire des choses inattendues.
jfriend00
40

Si vous écrivez:, if(x === true)ce ne sera vrai que pour x = vrai

Si vous écrivez:, if(x)il sera vrai pour tout x qui n'est pas: '' (chaîne vide), faux, nul, indéfini, 0, NaN.

Karaxuna
la source
(chaîne vide), false, null, undefined, 0, NaN
Oliboy50
N'oubliez pas NaNet -0.
haykam
8

Dans le clair "si" la variable sera forcée à un booléen et elle utilise toBoolean sur l'objet: -

    Argument Type   Result

    Undefined       false
    Null            false
    Boolean         The result equals the input argument (no conversion).
    Number          The result is false if the argument is +0, 0, or NaN;
                    otherwise the result is true.
    String          The result is false if the argument is the empty 
                    String (its length is zero); otherwise the result is true.
    Object          true.

Mais la comparaison avec === n'a pas de coercition de type, donc ils doivent être égaux sans coercition.

Si vous dites que l'objet n'est peut-être même pas un booléen, vous devrez peut-être considérer plus que juste vrai / faux.

if(x===true){
...
} else if(x===false){
....
} else {
....
}
QuentinUK
la source
5

Cela dépend de votre cas d'utilisation. Il peut être judicieux de vérifier le type aussi, mais s'il ne s'agit que d'un indicateur, ce n'est pas le cas.

Ven
la source
La ===comparaison n'effectue pas de coercition de type. Ainsi, le code de l'OP teste effectivement le type du drapeau. Il ne réussit que si la valeur est un booléen et est true.
Jesse Hallett
Permettez-moi de reformuler. Si vous savez que ce sera vrai ou faux, peu importe.
Ven
5

En général, il est plus propre et plus simple d'omettre le === true.

Cependant, en Javascript, ces déclarations sont différentes.

if (booleanValue)exécutera si booleanValueest truthy - autre chose que 0, false, '', NaN, nullet undefined.

if (booleanValue === true)ne s'exécutera que si booleanValueest précisément égal à true.

SLaks
la source
C'est précisément ce dont je veux être sûr, même si je veux seulement que boolValue soit vrai ou faux. La variable est définie sur vrai / faux plusieurs fois dans le code. Je sais que lorsque j'écris le code, mais si je vérifie à nouveau le code un an plus tard, c'est juste un gros point d'interrogation à moins que je ne relise tout, n'est-ce pas?
DirkZz
@aldanux: Oups; Je voulais dire ''.
SLaks
4

L' (===)opérateur d' identité se comporte de la même manière que l' (==)opérateur d' égalité sauf qu'aucune conversion de type n'est effectuée et que les types doivent être identiques pour être considérés comme égaux.

LOGICIEL Apollo
la source
Votre dernière phrase est fausse. Essayez vos deux déclarations if (booleanValue)et if (booleanValue==true)quand booleanValueest 2. Ces deux déclarations ne vous donnent pas le même résultat.
jfriend00
Intéressant. Je te prendrai au mot. Je pensais dans le monde ObjC / C / C ++, dans JS, je suppose que vous avez raison, car les types de données dans JS peuvent être modifiés et 2 == true ne quantifiera pas le si alors.
Apollo SOFTWARE
1
Voir ma réponse ci-dessus pour cet exemple spécifique. Cela a à voir avec la façon dont Javascript effectue la conversion automatique de type afin de comparer deux valeurs de types différents.
jfriend00
3

Puisque la valeur vérifiée est Booleanpréférable de l'utiliser directement pour moins de codage et du tout, il a fait de même==true

Alyafey
la source
2

Puisque vous avez déjà initialisé clairement en tant que booléen, je pense que l' ===opérateur n'est pas nécessaire.

Ensoleillé
la source
2

Si la variable ne peut prendre que des valeurs booléennes, il est raisonnable d'utiliser la syntaxe plus courte.

Si d'autres types peuvent potentiellement lui être attribués et que vous devez le distinguer truede 1ou "foo", vous devez utiliser === true.

Barmar
la source
2

Je pense que votre raisonnement est solide. Mais dans la pratique, j'ai constaté qu'il est beaucoup plus courant d'omettre la ===comparaison. Je pense qu'il y a trois raisons à cela:

  1. Cela n'ajoute généralement pas à la signification de l'expression - c'est dans les cas où la valeur est connue pour être booléenne de toute façon.
  2. Parce qu'il y a beaucoup d'incertitude de type dans JavaScript, forcer une vérification de type a tendance à vous mordre lorsque vous obtenez un inattendu undefinedounull valeur valeur . Souvent, vous voulez simplement que votre test échoue dans de tels cas. (Bien que j'essaie d'équilibrer ce point de vue avec la devise «échouer rapidement»).
  3. Les programmeurs JavaScript aiment jouer rapidement et librement avec les types - en particulier dans les expressions booléennes - parce que nous le pouvons.

Prenons cet exemple:

var someString = getInput();
var normalized = someString && trim(someString);  
// trim() removes leading and trailing whitespace

if (normalized) {
    submitInput(normalized);
}

Je pense que ce genre de code n'est pas rare. Il gère les cas où les getInput()retours undefined, nullou une chaîne vide. En raison des deux évaluations booléennessubmitInput() n'est appelée que si l'entrée donnée est une chaîne contenant des caractères non blancs.

En JavaScript &&renvoie son premier argument s'il est faux ou son deuxième argument si le premier argument est vrai; il en normalizedsera de même undefinedsisomeString était indéfini et ainsi de suite. Cela signifie qu'aucune des entrées des expressions booléennes ci-dessus n'est en fait une valeur booléenne.

Je sais que beaucoup de programmeurs qui sont habitués à une forte vérification de type grincent des dents lorsqu'ils voient du code comme celui-ci. Mais notez que l'application d'un typage fort nécessiterait probablement des vérifications explicites nullou des undefinedvaleurs, ce qui encombrerait le code. En JavaScript, ce n'est pas nécessaire.

Jesse Hallett
la source
1

Cela dépend. Si vous craignez que votre variable puisse devenir quelque chose qui se résout à TRUE. Une vérification rigoureuse est alors indispensable. Sinon, c'est à vous. Cependant, je doute que la syntaxe whatever == TRUEne déroute jamais quiconque savait ce qu'il faisait.

usumoio
la source
1

En Javascript, l'idée de booléen est assez ambiguë. Considère ceci:

 var bool = 0 
 if(bool){..} //evaluates to false

 if(//uninitialized var) //evaluates to false

Ainsi, lorsque vous utilisez une instruction if (ou toute autre instruction de contrôle), il n'est pas nécessaire d'utiliser un type var "booléen". Par conséquent, à mon avis, la partie "=== true" de votre déclaration est inutile si vous savez que c'est un booléen, mais absolument nécessaire si votre valeur est une variable "véridique" ambiguë. Plus d'informations sur les booléens en javscript peuvent être trouvées ici .

ReposRobot
la source
1

Peut également être testé avec un objet booléen, si vous devez tester un objet error={Boolean(errors.email)}

Igor Pavlenko
la source