booleano in un'istruzione if


144

Oggi ho ricevuto un'osservazione sul codice considerando il modo in cui controllo se una variabile è vera o falsa in un compito scolastico.

Il codice che avevo scritto era qualcosa del genere:

var booleanValue = true;

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

Dissero che era meglio / meglio scrivere in questo modo:

var booleanValue = true;

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

L'osservazione che ho ottenuto sulla parte "=== true" era che non era necessaria e poteva creare confusione.

Tuttavia, la mia idea è che è meglio verificare se la variabile è un valore booleano o meno, soprattutto perché Javascript è un linguaggio loosetyped.

Nel secondo esempio una stringa restituirebbe anche "qualcosa";

Quindi la mia domanda; È più comodo perdere la parte "=== true" in futuro o è buona norma controllare anche il tipo di variabile.

Modifica: Nel mio codice "reale" il valore booleano indica se un'immagine è stata eliminata o meno, quindi gli unici valori che boolValue dovrebbe mai avere è vero o falso.

0 e 1 per esempio non dovrebbero essere in quella variabile.


4
è leggibile e buona pratica usare ===
Piyas De

2
+1 per === true. Evita la confusione !!
Gashu,

1
@gashu Considerare [0] === truevalutato come falso.
Riposo Robot

1
@Jlange non dovrebbe? Spiega
gashu,

Quello che intendevo con questo, è che se si volesse semplicemente verificare l'esistenza di una "verità", quell'affermazione fallirebbe, anche se dovrebbe essere considerata vera ([0] valuta vera ma non senza conversione del tipo). Dipende davvero da cosa stai cercando di realizzare con la tua affermazione. Utilizzare === truequando è necessario assicurarsi che la condizione sia esattamente uguale a true.
Riposo Robot

Risposte:


222

Prima di tutto, i fatti:

if (booleanValue)

Soddisfarrà l' ifaffermazione per qualsiasi valore di verità di booleanValueinclusione true, qualsiasi numero diverso da zero, qualsiasi valore di stringa non vuoto, qualsiasi riferimento a oggetto o array, ecc ...

D'altro canto:

if (booleanValue === true)

Ciò soddisferà la ifcondizione solo se booleanValueè esattamente uguale a true. Nessun altro valore di verità lo soddisferà.

D'altra parte se lo fai:

if (someVar == true)

Quindi, ciò che Javascript farà è digitare coerce trueper abbinare il tipo di someVare quindi confrontare le due variabili. Ci sono molte situazioni in cui questo non è probabilmente ciò che si vorrebbe. Per questo ==motivo , nella maggior parte dei casi si desidera evitare perché esiste un insieme abbastanza lungo di regole su come Javascript digita forzare due cose per essere dello stesso tipo e, a meno che non si capiscano tutte quelle regole e si possa anticipare tutto ciò che l'interprete JS potrebbe fare quando dati due tipi diversi (che la maggior parte degli sviluppatori JS non possono), probabilmente vorrai evitare del ==tutto.

Come esempio di quanto possa essere confuso:

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 

Per quanto riguarda il valore 2, potresti pensare che 2sia un valore veritiero in modo da confrontarlo favorevolmente true, ma non è così che funziona la coercizione del tipo. Sta convertendo il valore della mano destra in modo che corrisponda al tipo del valore della mano sinistra, quindi si sta convertendo truenel numero, 1quindi sta confrontando 2 == 1che non è certamente quello che probabilmente intendevi.

Quindi, il compratore sta attento. È probabilmente meglio evitarlo ==in quasi tutti i casi a meno che tu non conosca esplicitamente i tipi che confronterai e saprai come funzionano tutti i possibili algoritmi di coercizione dei tipi.


Quindi, dipende davvero dai valori previsti booleanValuee da come si desidera che il codice funzioni. Se sai in anticipo che avrà sempre un valore trueo false, confrontandolo esplicitamente con

if (booleanValue === true)

è solo un codice extra e non necessario e

if (booleanValue)

è più compatto e probabilmente più pulito / migliore.

Se, d'altra parte, non sai cosa booleanValuepotrebbe essere e vuoi testare se è veramente impostato su truesenza altre conversioni di tipo automatiche consentite, allora

if (booleanValue === true)

non è solo una buona idea, ma necessaria.


Ad esempio, se si guarda all'implementazione di .on()in jQuery, ha un valore di ritorno opzionale. Se il callback ritorna false, jQuery interromperà automaticamente la propagazione dell'evento. In questo caso specifico, dal momento che jQuery vuole SOLO propagazione fermarsi se falseè stato restituito, controllano l'esplicitamente valore restituito per === falseperché non vogliono undefinedo 0o ""o qualsiasi altra cosa che verrà automaticamente digitare-convert false per soddisfare anche il confronto.

Ad esempio, ecco l'evento jQuery che gestisce il codice di richiamata:

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

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

Puoi vedere che jQuery sta cercando esplicitamente ret === false.

Ma ci sono anche molti altri posti nel codice jQuery in cui un controllo più semplice è appropriato dato il desiderio del codice. Per esempio:

// The DOM ready check for Internet Explorer
function doScrollCheck() {
    if ( jQuery.isReady ) {
        return;
    }
    ...

Ho pensato a questa domanda per un po ', ma non ho avuto la possibilità di trovare nessuno a cui chiedere. Gradirei se potessi dare un'occhiata. stackoverflow.com/questions/32615466/…
mmm

Questa risposta non è completamente corretta. 'x == true' non sarà vero per numeri diversi da zero.
Teemoh,

@Teemoh - Non capisco il tuo commento. Vedi jsfiddle.net/jfriend00/89h8d8tm .
jfriend00,

1
Voglio solo dire che 'if (x)' non è lo stesso di 'if (x == true)', come hai scritto nel primo paragrafo della tua risposta. 'if (x)' convertirà esplicitamente 'x' nella sua rappresentazione booleana. 'if (x == true)' utilizzerà l'algoritmo di confronto degli abstract di EcmaScript. Hai scritto che 'if (x == true)' sarà vero per qualsiasi numero diverso da zero o stringa non vuota o qualsiasi oggetto. Questo è semplicemente sbagliato. Se eseguo il tuo esempio con 2 anziché 1, non funzionerà.
Teemoh,

2
@Teemoh - Vedo il tuo punto. Risposta corretta e chiarita e ho aggiunto una sezione sulla coercizione del tipo con un esempio che mostra come può fare cose inaspettate.
jfriend00,

40

Se scrivi if(x === true):, sarà vero solo per x = vero

Se scrivi if(x):, sarà vero per qualsiasi x che non sia: '' (stringa vuota), falso, nullo, non definito, 0, NaN.


(stringa vuota), falso, nullo, non definito, 0, NaN
Oliboy50

Non dimenticare NaNe -0.
Hayak

8

Nel semplice "if" la variabile sarà forzata a un valore booleano e utilizza toBoolean sull'oggetto: -

    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.

Ma il confronto con === non ha alcun tipo di coercizione, quindi devono essere uguali senza coercizione.

Se stai dicendo che l'oggetto potrebbe non essere nemmeno un booleano, allora potresti dover considerare più di un vero / falso.

if(x===true){
...
} else if(x===false){
....
} else {
....
}

5

Dipende dal tuo caso d'uso. Potrebbe avere senso controllare anche il tipo, ma se è solo una bandiera, non lo è.


Il ===confronto non esegue la coercizione del tipo. Quindi il codice del PO verifica efficacemente il tipo di bandiera. Ha successo solo se il valore è un valore booleano ed è vero.
Jesse Hallett,

Lasciami riformulare. Se sai che sarà vero o falso, non importa.
Ven

5

In generale, è più semplice e pulito omettere === true.

Tuttavia, in Javascript, queste affermazioni sono diverse.

if (booleanValue)eseguirà se booleanValueè truthy - qualcosa di diverso 0, false, '', NaN, null, e undefined.

if (booleanValue === true)verrà eseguito solo se booleanValueè esattamente uguale a true.


Il che è esattamente ciò di cui voglio essere sicuro, anche quando voglio solo che boolValue sia vero o falso. La variabile viene impostata su true / false più volte nel codice. Lo so quando scrivo il codice, ma se ricontrollo il codice un anno dopo, è solo un grande punto interrogativo a meno che non rilegga tutto bene?
DirkZz,

@aldanux: Oops; Intendevo ''.
SLaks

4

L' (===)operatore di identità si comporta in modo identico (==)all'operatore di uguaglianza , tranne per il fatto che non viene eseguita alcuna conversione di tipo e i tipi devono essere gli stessi per essere considerati uguali.


L'ultima frase è sbagliata. Prova le tue due dichiarazioni if (booleanValue)e if (booleanValue==true)quando lo booleanValueè 2. Queste due affermazioni non danno lo stesso risultato.
jfriend00,

Interessante. Prenderò la tua parola per questo. Stavo pensando nel mondo ObjC / C / C ++, in JS presumo che tu sia corretta, dal momento che i tipi di dati in JS possono essere cambiati e 2 == true non quantificerà se allora.
SOFTWARE Apollo

1
Vedi la mia risposta sopra per questo esempio specifico. Ha a che fare con il modo in cui Javascript esegue la conversione automatica dei tipi per confrontare due valori di tipi diversi.
jfriend00,

3

Dal momento che il valore verificato è Booleanpreferibile usarlo direttamente per meno codice e lo stesso ha fatto==true


2

Dato che hai già inizializzato chiaramente come bool, penso che l' ===operatore non sia richiesto.


2

Se la variabile può assumere solo valori booleani, è ragionevole utilizzare la sintassi più breve.

Se può potenzialmente essere assegnato ad altri tipi e devi distinguere trueda 1o "foo", allora devi usare === true.


2

Penso che il tuo ragionamento sia corretto. Ma in pratica ho scoperto che è molto più comune omettere il ===confronto. Penso che ci siano tre ragioni per questo:

  1. Di solito non si aggiunge al significato dell'espressione - questo è nei casi in cui il valore è comunque noto come booleano.
  2. Poiché in JavaScript esiste una grande incertezza di tipo, forzare un controllo del tipo tende a morderti quando ricevi un valore undefinedo un imprevisto null. Spesso vuoi solo che il test fallisca in questi casi. (Anche se provo a bilanciare questa visione con il motto "fail fast").
  3. Ai programmatori JavaScript piace giocare a tutto tondo con i tipi, specialmente nelle espressioni booleane, perché possiamo.

Considera questo esempio:

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

if (normalized) {
    submitInput(normalized);
}

Penso che questo tipo di codice non sia raro. Gestisce i casi in cui getInput()i rendimenti undefined, nullo una stringa vuota. A causa delle due valutazioni booleane submitInput()viene chiamato solo se l'input dato è una stringa che contiene caratteri non bianchi.

In JavaScript &&restituisce il suo primo argomento se è falso o il suo secondo argomento se il primo argomento è vero; così normalizedsarà undefinedse someStringnon fosse definito e così via. Ciò significa che nessuno degli input alle espressioni booleane sopra sono in realtà valori booleani.

So che molti programmatori sono abituati a forti contrattempi di controllo del tipo quando vedono codice come questo. Tuttavia, l'applicazione di una tipizzazione forte richiederebbe probabilmente controlli nullo undefinedvalori espliciti , il che ingombrerebbe il codice. In JavaScript non è necessario.


1

Questo dipende. Se sei preoccupato che la tua variabile possa finire come qualcosa che si risolve in VERO. Quindi un controllo approfondito è un must. Altrimenti dipende da te. Tuttavia, dubito che la sintassi whatever == TRUEconfonderebbe mai chiunque sapesse cosa stavano facendo.


1

In Javascript l'idea del booleano è abbastanza ambigua. Considera questo:

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

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

Pertanto, quando si utilizza un'istruzione if (o qualsiasi altra istruzione di controllo), non è necessario utilizzare una variante "booleana" var. Pertanto, a mio avviso, la parte "=== vera" della tua affermazione non è necessaria se sai che è un valore booleano, ma assolutamente necessaria se il tuo valore è una ambigua "verità" var. Maggiori informazioni sui booleani in javscript sono disponibili qui .



1

Inoltre può essere testato con oggetto booleano, se è necessario testare un oggetto error={Boolean(errors.email)}

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.