Come posso convertire una stringa in booleano in JavaScript?


2553

Posso convertire una stringa che rappresenta un valore booleano (ad esempio, "vero", "falso") in un tipo intrinseco in JavaScript?

Ho un modulo nascosto in HTML che viene aggiornato in base alla selezione di un utente all'interno di un elenco. Questo modulo contiene alcuni campi che rappresentano valori booleani e sono dinamicamente popolati con un valore booleano intrinseco. Tuttavia, una volta inserito questo valore nel campo di input nascosto, diventa una stringa.

L'unico modo in cui sono riuscito a trovare il valore booleano del campo, una volta convertito in una stringa, era quello di dipendere dal valore letterale della sua rappresentazione in stringa.

var myValue = document.myForm.IS_TRUE.value;
var isTrueSet = myValue == 'true';

C'è un modo migliore per raggiungere questo obiettivo?


50
"C'è un modo migliore per raggiungere questo obiettivo?" - c'è sicuramente un modo peggiore: Dstring=(string==String(string?true:false))?(string?true:false):(!string?true:fa‌​lse);
Mark K Cowan,

3
function parseBool(val) { return val === true || val === "true" }
Gestisci

1
@Markfunction checkBool(x) { if(x) {return true;} else {return false;} }
Sebi,

2
@Sebi: Hai dimenticato di documentarlo:if (checkBool(x) != false) { ... } else { ... }
Mark K Cowan,

3
!!(parseInt(value) || value === "true")
Andrew Luca,

Risposte:


3483

Fare:

var isTrueSet = (myValue == 'true');

Potresti renderlo più rigoroso utilizzando l'operatore di identità ( ===), che non effettua conversioni di tipo implicite quando le variabili confrontate hanno tipi diversi, anziché l'operatore di uguaglianza ( ==).

var isTrueSet = (myValue === 'true');

Non:

Probabilmente dovresti essere cauto sull'uso di questi due metodi per le tue esigenze specifiche:

var myBool = Boolean("false");  // == true

var myBool = !!"false";  // == true

Qualsiasi stringa che non è la stringa vuota verrà valutata trueutilizzandola. Sebbene siano i metodi più puliti che posso pensare riguardo alla conversione booleana, penso che non siano quello che stai cercando.


196
myValue === 'true';è esattamente equivalente a myValue == 'true';. Non v'è alcun vantaggio nell'utilizzo di ===sopra ==qui.
Tim Down,

551
Seguo i consigli e l'uso di Crockford=== e !==ogni volta che ha senso, il che è quasi sempre.
Guinea il

55
Che dire di "TRUE" in maiuscolo, ad esempio?
BMiner

102
@guinaps Di solito seguo il consiglio di Crockford, ma lo scenario ==vs. ===è uno dei pochi in cui non lo faccio. Sono completamente in disaccordo sul fatto che "quasi sempre" ha senso usare ===. Esistono lingue tipicamente vaghe perché non vogliamo preoccuparci del tipo; se controlliamo qualcosa del genere if (price >= 50)non ci interessa se è iniziato come una stringa. Dico, la maggior parte delle volte, vogliamo che i tipi vengano manipolati. Nei rari casi in cui non vogliamo digitare giocoleria (ad es. if (price === null)), Allora usiamo ===. Questo è quello che ho fatto per anni e non ho mai avuto problemi.
JMTyler,

169
@JMTyler potrebbe trascurare il programmatore di manutenzione in arrivo. Utilizzare sempre l'operatore di confronto corretto! Se conosci "di sicuro" i tipi su entrambi i lati, ma non usi ===, non avrò questa conoscenza quando guarderò il tuo codice in seguito. Se il tuo codice viene riutilizzato, questo può diventare un incubo. Se vuoi davvero 'manipolare' i tuoi tipi come dici, allora usa '==', ma troppi sviluppatori JS inciamperanno su questo troppo facilmente, meglio per stringere il tuo codice. Con quale frequenza desidero che la stringa 'false' significhi booleano 'true'?
aikeru,

687

avvertimento

Questa risposta legacy molto votata è tecnicamente corretta ma copre solo uno scenario molto specifico, quando il valore della stringa è ESATTAMENTE "true"o "false".

Una stringa json non valida passata a queste funzioni di seguito genererà un'eccezione .


Risposta originale:

Che ne dite di?

JSON.parse("True".toLowerCase());

o con jQuery

$.parseJSON("TRUE".toLowerCase());

62
Il problema è che molti potenziali valori generano un errore di analisi che interrompe l'esecuzione di JS. Quindi eseguire JSON.parse ("FALSE") bombarda Javascript. Il punto della domanda, penso, non è semplicemente risolvere questi casi esatti, ma anche essere resilienti ad altri casi.
BishopZ,

3
@Luke questa soluzione è esattamente ciò di cui avevo bisogno; beh, avvolgendolo in un tentativo ... cattura però. Volevo convertire in bool solo se fosse un valore booleano nella stringa; altrimenti, basta usare la stringa fornita. Questo funziona! Grazie.
jedmao,

47
È abbastanza semplice dirlo in JSON.parse("TRUE".toLowerCase())modo da poter analizzare correttamente.
Yuck,

27
perché ci sono così tanti voti positivi? Questo è inefficiente e orribile. Qual è il prossimo? 'true'.length === 4?
Maksim Vi.

21
@MaksimVi. typeof str==="string"&& str.length===4&& str.charAt(0)==="t" && str.charAt(1)==="r" && str.charAt(2)==="u" && str.charAt(3)==="e"&& true===true && true!==false && false===false// solo per essere sicuri
Vitim.us

223
stringToBoolean: function(string){
    switch(string.toLowerCase().trim()){
        case "true": case "yes": case "1": return true;
        case "false": case "no": case "0": case null: return false;
        default: return Boolean(string);
    }
}

43
In realtà può essere semplificato. 1) Non è necessario per verificare "true", "yes"e "1". 2) toLowerCasenon ritorna null. 3) Boolean(string)è uguale a string!==""qui. =>switch(string.toLowerCase()) {case "false": case "no": case "0": case "": return false; default: return true;}
Robert,

15
@Robert, bello, ma preferirei avere l'impostazione predefinita come falseinvece.
drigoangelo,

@drigoangelo Avere default: return true;è certamente possibile. Ma cambierebbe il comportamento della funzione.
Robert,

2
Ho pensato che questo era la migliore risposta, e ha voluto approfondire qui: stackoverflow.com/questions/263965/...
BrDaHa

9
se stai normalizzando i dati chiamando .toLowerCase (), allora potresti non voler gettare in trim () anche per eliminare gli spazi bianchi
jCuga

174

Penso che questo sia molto universale:

if (String(a) == "true") ...

Va:

String(true) == "true"     //returns true
String(false) == "true"    //returns false
String("true") == "true"   //returns true
String("false") == "true"  //returns false

20
Quando puoi ricevere una stringa in maiuscolo o booleano, alloraString(a).toLowerCase() === 'true'
pauloya,

String("what about input like this that isn't a bool?") == "true"
Thomas Eding,

6
@ThomasEding false ... cosa vuoi che ritorni?
Snowburnt

2
potrebbe anche accorciare non usando il String()costruttore:true+'' === 'true' // true
Todd

1
A proposito, per 1 o 0 dovrebbe anche essere lanciato per falso o vero
Miguel

128

Ricorda di abbinare il caso:

var isTrueSet = (myValue.toLowerCase() === 'true');

Inoltre, se è una casella di controllo di un elemento del modulo, puoi anche rilevare se la casella di controllo è selezionata:

var isTrueSet = document.myForm.IS_TRUE.checked;

Supponendo che se è selezionato, è "impostato" uguale a vero. Questo viene valutato come vero / falso.


3
Questo genererà un'eccezione, se myValuesuccede null, trueo qualche altro tipo ...
mik01aj,

116

Puoi usare espressioni regolari:

/*
 * Converts a string to a bool.
 *
 * This conversion will:
 *
 *  - match 'true', 'on', or '1' as true.
 *  - ignore all white-space padding
 *  - ignore capitalization (case).
 *
 * '  tRue  ','ON', and '1   ' will all evaluate as true.
 *
 */
function strToBool(s)
{
    // will match one and only one of the string 'true','1', or 'on' rerardless
    // of capitalization and regardless off surrounding white-space.
    //
    regex=/^\s*(true|1|on)\s*$/i

    return regex.test(s);
}

Se ti piace estendere la classe String puoi fare:

String.prototype.bool = function() {
    return strToBool(this);
};

alert("true".bool());

Per quelli (vedi i commenti) che vorrebbero estendere l'oggetto String per ottenere questo, ma sono preoccupati per l'enumerabilità e sono preoccupati di scontrarsi con altro codice che estende l'oggetto String:

Object.defineProperty(String.prototype, "com_example_bool", {
    get : function() {
        return (/^(true|1)$/i).test(this);
    }
});
alert("true".com_example_bool);

(Ovviamente non funziona nei browser più vecchi e Firefox mostra false mentre Opera, Chrome, Safari e IE mostrano true. Bug 720760 )


10
Puoi sempre aggiungere il prefisso alla funzione se hai paura che interferisca con qualche altro codice. Se qualche codice si interrompe ancora, quel codice è troppo fragile e dovrebbe essere corretto. Se la tua funzione aggiunta rende l'oggetto troppo pesante dove causa un problema di prestazioni per altro codice, ovviamente, non vuoi farlo. Ma non penso che sia generalmente una cattiva idea estendere gli oggetti incorporati. Inoltre, non sarebbero estendibili pubblicamente se fosse così.
Shadow2531,

41
@DTrejo @Szymon Non sono d'accordo. Questo è esattamente il tipo di sovraccarico a cui è destinato il prototipo. Se hai paura che si rompa il codice (scarso) su cui si basa for..in, ci sono modi per nascondere le proprietà dall'enumerazione. Vedere Object.defineProperty.
devios1,

Per seguire la convenzione, la chiamereiparseBool
guzart,

8
L'analisi booleana non appartiene alla classe String .. finiresti con qualsiasi quantità di parser di immondizia e conversione lì. -1 alla modifica dei prototipi in generale. -1 a soluzioni che non funzionano su più browser. -1 per un design scadente.
Thomas W,

1
Ecco un confronto delle prestazioni di tutte le risposte. stackoverflow.com/a/28588344/2824333
Sospedra

50

Wood-eye stai attento. Dopo aver visto le conseguenze dopo aver applicato la risposta migliore con oltre 500 voti, mi sento in dovere di pubblicare qualcosa che è effettivamente utile:

Cominciamo con il modo più breve, ma molto rigoroso:

var str = "true";
var mybool = JSON.parse(str);

E termina con un modo corretto e più tollerante:

var parseBool = function(str) 
{
    // console.log(typeof str);
    // strict: JSON.parse(str)

    if(str == null)
        return false;

    if (typeof str === 'boolean')
    {
        return (str === true);
    } 

    if(typeof str === 'string')
    {
        if(str == "")
            return false;

        str = str.replace(/^\s+|\s+$/g, '');
        if(str.toLowerCase() == 'true' || str.toLowerCase() == 'yes')
            return true;

        str = str.replace(/,/g, '.');
        str = str.replace(/^\s*\-\s*/g, '-');
    }

    // var isNum = string.match(/^[0-9]+$/) != null;
    // var isNum = /^\d+$/.test(str);
    if(!isNaN(str))
        return (parseFloat(str) != 0);

    return false;
}

test:

var array_1 = new Array(true, 1, "1",-1, "-1", " - 1", "true", "TrUe", "  true  ", "  TrUe", 1/0, "1.5", "1,5", 1.5, 5, -3, -0.1, 0.1, " - 0.1", Infinity, "Infinity", -Infinity, "-Infinity"," - Infinity", " yEs");

var array_2 = new Array(null, "", false, "false", "   false   ", " f alse", "FaLsE", 0, "00", "1/0", 0.0, "0.0", "0,0", "100a", "1 00", " 0 ", 0.0, "0.0", -0.0, "-0.0", " -1a ", "abc");


for(var i =0; i < array_1.length;++i){ console.log("array_1["+i+"] ("+array_1[i]+"): " + parseBool(array_1[i]));}

for(var i =0; i < array_2.length;++i){ console.log("array_2["+i+"] ("+array_2[i]+"): " + parseBool(array_2[i]));}

for(var i =0; i < array_1.length;++i){ console.log(parseBool(array_1[i]));}
for(var i =0; i < array_2.length;++i){ console.log(parseBool(array_2[i]));}

Ricorda che i browser più vecchi potrebbero aver bisogno di un polyfill JSON se usi il primo metodo.
DRaehal,

1
Quanto è veloce il cast di una stringa "falsa" su un falsevalore booleano JSON.parse? In termini di CPU, prestazioni della memoria
Verde

Non sarebbe più semplice iniziare con if (str) {...} per eliminare qualcosa di già falso? E all'interno di questa condizione if, devi solo preoccuparti di tornare true, perché finisci già con return false!
Larphoid

Tieni presente che puoi accorciare molti dei test di stringa con (["true", "yes", "1"]. IndexOf (str.toLowerCase (). Trim ())! = -1) e utilizzare un fallback di Boolean (str) per coprire cose come 'null'
Scott

38

Ho pensato che la risposta di @Steven fosse la migliore e mi sono occupata di molti più casi che se il valore in entrata fosse solo una stringa. Volevo estenderlo un po 'e offrire quanto segue:

function isTrue(value){
    if (typeof(value) === 'string'){
        value = value.trim().toLowerCase();
    }
    switch(value){
        case true:
        case "true":
        case 1:
        case "1":
        case "on":
        case "yes":
            return true;
        default: 
            return false;
    }
}

Non è necessario coprire tutti i falsecasi se si conoscono già tutti i truecasi di cui si dovrebbe tenere conto. Puoi passare qualsiasi cosa in questo metodo che potrebbe passare per un truevalore (o aggiungerne altri, è piuttosto semplice), e tutto il resto sarebbe consideratofalse


Uso questo in quanto copre le cose che si ottengono dagli attributi ElementNodes XML / HTML comeautocomplete="on"
philk

2
Vorrei aggiungere .trim () prima di toLowerCase ()
Luis Lobo Borobia il

34

Soluzione universale con analisi JSON:

function getBool(val) {
    return !!JSON.parse(String(val).toLowerCase());
}

getBool("1"); //true
getBool("0"); //false
getBool("true"); //true
getBool("false"); //false
getBool("TRUE"); //true
getBool("FALSE"); //false

AGGIORNAMENTO (senza JSON):

function getBool(val){ 
    var num = +val;
    return !isNaN(num) ? !!num : !!String(val).toLowerCase().replace(!!0,'');
}

Ho anche creato violino per testarlo http://jsfiddle.net/remunda/2GRhG/


1
La versione 'senza JSON' ha qualche difetto: val = "0"; console.log (!! (+ val || String (val) .toLowerCase (). replace (!! 0, ''))); produce true
Etienne,

3
getBool(undefined)andrà in crash Quando si utilizza la versione JSON originale e verrà restituito true per la 2a versione. Ecco una terza versione che restituisce false: function getBool (val) {var num; return val! = null && (! isNaN (num = + val)? !! num: !! String (val) .toLowerCase (). replace (!! 0, '')); }
Ron Martinez,

31

La tua soluzione va bene

===In questo caso l' utilizzo sarebbe semplicemente sciocco, poiché il campo valuesarà sempre a String.


17
Perché pensi che sarebbe sciocco da usare ===? In termini di prestazioni sarebbe esattamente lo stesso se entrambi i tipi sono stringhe. Ad ogni modo, preferisco usare ===poiché evito sempre l'uso di ==e !=. Giustificazioni: stackoverflow.com/questions/359494/...
Mariano Desanze

3
Dal momento che valuesarà sempre string=====sono sciocchi. Entrambi sono lo strumento giusto per questo lavoro. Differiscono solo quando i tipi non sono uguali. In tal caso, ===ritorna semplicemente falsementre ==esegue un intricato algoritmo di coercizione del tipo prima del confronto.
Robert,

23
var falsy = /^(?:f(?:alse)?|no?|0+)$/i;
Boolean.parse = function(val) { 
    return !falsy.test(val) && !!val;
};

Ciò restituisce falseper ogni valore falsy e trueper ogni valore truthy eccezione 'false', 'f', 'no', 'n', e '0'(case-insensitive).

// False
Boolean.parse(false);
Boolean.parse('false');
Boolean.parse('False');
Boolean.parse('FALSE');
Boolean.parse('f');
Boolean.parse('F');
Boolean.parse('no');
Boolean.parse('No');
Boolean.parse('NO');
Boolean.parse('n');
Boolean.parse('N');
Boolean.parse('0');
Boolean.parse('');
Boolean.parse(0);
Boolean.parse(null);
Boolean.parse(undefined);
Boolean.parse(NaN);
Boolean.parse();

//True
Boolean.parse(true);
Boolean.parse('true');
Boolean.parse('True');
Boolean.parse('t');
Boolean.parse('yes');
Boolean.parse('YES');
Boolean.parse('y');
Boolean.parse('1');
Boolean.parse('foo');
Boolean.parse({});
Boolean.parse(1);
Boolean.parse(-1);
Boolean.parse(new Date());

20

L'oggetto booleano non ha un metodo di "analisi". Boolean('false')ritorna vero, quindi non funzionerà. !!'false'ritorna anche true, quindi non funzionerà.

Se si desidera che la stringa 'true'restituisca il valore booleano truee che la stringa 'false'restituisca il valore booleano false, utilizzare la soluzione più semplice eval(). eval('true')restituisce true e eval('false')restituisce false. Tenere presente le implicazioni sulle prestazioni quando si utilizza eval()però.


Per capire cosa è "sbagliato" (o giusto) con eval - controlla articoli come javascriptweblog.wordpress.com/2010/04/19/how-evil-is-eval o cerca su stackoverflow "Javascript eval malware"
GrahamMc

2
Sono d'accordo che var isTrueSet = (myValue === 'true');sia la risposta migliore.
thdoan

Mi piace che sia conciso. Ma fallisce in modo spettacolare per il caso base di eval('TRUE'); provando ancora una volta, questo eval()è male.
Pupazzo di neve,

@Area 51 Detective Fiction, allo stesso modo, JSON.parse('TRUE')dalla risposta seguente fallisce anche in modo spettacolare. È abbastanza facile forzare una condizione di errore in JavaScript (o in qualsiasi lingua, per quella materia). Per tenere conto di questo, si dovrebbe normalizzare la stringa di prima, ad esempio,var myValue = document.myForm.IS_TRUE.value.toLowerCase(); var isTrueSet = (myValue==='true' || myValue==='false') ? eval(myValue) : false;
thdoan

1
@ 10basetom: abbastanza corretto. Dovresti includere .toLowerCase()nella risposta il mio punto. Non sto cercando di forzare nulla. Il maiuscolo TRUEè un valore abbastanza comune per essere restituito da molti widget dell'interfaccia utente.
Pupazzo di neve

18

Questo è stato preso dalla risposta accettata, ma in realtà ha un punto molto debole, e sono scioccato da come ha ottenuto quel conteggio di voti positivi, il problema con esso che devi considerare il caso della stringa perché è sensibile al maiuscolo / minuscolo

var isTrueSet = (myValue.toLowerCase() === 'true');

16

Io uso il seguente:

function parseBool(b) {
    return !(/^(false|0)$/i).test(b) && !!b;
}

Questa funzione esegue la solita coercizione booleana ad eccezione delle stringhe "false" (senza distinzione tra maiuscole e minuscole) e "0".


16

Ci sono molte risposte ed è difficile sceglierne una. Nel mio caso, ho la priorità delle prestazioni quando scelgo , quindi creo questo jsPerf che spero possa far luce qui.

Breve risultato (più alto è il migliore):

  1. Dichiarazione condizionale : 2.826.922
  2. Cambia custodia sull'oggetto Bool : 2.825.469
  3. Casting su JSON : 1.867.774
  4. !! conversioni : 805.322
  5. Prototipo di stringa : 713.637

Sono collegati alla relativa risposta in cui è possibile trovare ulteriori informazioni (pro e contro) su ciascuno; specialmente nei commenti.


"qualcosa è andato storto" durante il tentativo di visualizzare il test
jsPerf

13
Boolean.parse = function (str) {
  switch (str.toLowerCase ()) {
    case "true":
      return true;
    case "false":
      return false;
    default:
      throw new Error ("Boolean.parse: Cannot convert string to boolean.");
  }
};

2
Puoi usare true.toString () invece di "true" per essere ancora più pulito :-)
tillda

Non cambiare globali, cercare di mantenere le modifiche isolato, forse creare un nuovo function parseBooleaninvece
Acciaio Cervello

13

L'espressione che stai cercando è semplicemente

/^true$/i.test(myValue)

come in

var isTrueSet = /^true$/i.test(myValue);

Ciò verifica myValueun'espressione regolare, senza distinzione tra maiuscole e minuscole e non modifica il prototipo.

Esempi:

/^true$/i.test("true"); // true
/^true$/i.test("TRUE"); // true
/^true$/i.test("tRuE"); // true
/^true$/i.test(" tRuE"); // false (notice the space at the beginning)
/^true$/i.test("untrue"); // false (some other solutions here will incorrectly return true
/^true$/i.test("false");// returns false
/^true$/i.test("xyz");  // returns false

12

Per convertire sia stringa ("vero", "falso") che booleano in booleano

('' + flag) === "true"

Dove flagpuò essere

 var flag = true
 var flag = "true"
 var flag = false
 var flag = "false"

12

Ci sono già così tante risposte disponibili. Ma il seguito può essere utile in alcuni scenari.

// One can specify all values against which you consider truthy
var TRUTHY_VALUES = [true, 'true', 1];

function getBoolean(a) {
    return TRUTHY_VALUES.some(function(t) {
        return t === a;
    });
}

Questo può essere utile laddove un esempio con valori non booleani.

getBoolean('aa'); // false
getBoolean(false); //false
getBoolean('false'); //false

getBoolean('true'); // true
getBoolean(true); // true
getBoolean(1); // true

10

perché non provi qualcosa del genere?

Boolean(JSON.parse((yourString.toString()).toLowerCase()));

Restituirà un errore quando viene fornito un altro testo anziché vero o falso indipendentemente dal caso e acquisirà anche i numeri come

// 0-> false
// any other number -> true

10

Questa funzione può gestire sia string / booleane true / false.

function stringToBoolean(val){
    var a = {
        'true':true,
        'false':false
    };
    return a[val];
}

Dimostrazione di seguito:

function stringToBoolean(val) {
  var a = {
    'true': true,
    'false': false
  };
  return a[val];
}

console.log(stringToBoolean("true"));

console.log(typeof(stringToBoolean("true")));

console.log(stringToBoolean("false"));

console.log(typeof(stringToBoolean("false")));

console.log(stringToBoolean(true));

console.log(typeof(stringToBoolean(true)));

console.log(stringToBoolean(false));

console.log(typeof(stringToBoolean(false)));

console.log("=============================================");
// what if value was undefined? 
console.log("undefined result:  " + stringToBoolean(undefined));
console.log("type of undefined result:  " + typeof(stringToBoolean(undefined)));
console.log("=============================================");
// what if value was an unrelated string?
console.log("unrelated string result:  " + stringToBoolean("hello world"));
console.log("type of unrelated string result:  " + typeof(stringToBoolean(undefined)));


9

Sto usando questo

String.prototype.maybeBool = function(){

    if ( ["yes", "true", "1", "on"].indexOf( this.toLowerCase() ) !== -1 ) return true;
    if ( ["no", "false", "0", "off"].indexOf( this.toLowerCase() ) !== -1 ) return false;

    return this;

}

"on".maybeBool(); //returns true;
"off".maybeBool(); //returns false;
"I like js".maybeBool(); //returns "I like js"

Questo va bene, ma funziona solo con il tipo String. Immagina che questo debba essere usato da una variabile forse "true"o true. Se arriva il secondo, questo non funzionerà. È possibile fare un document.prototypeuso questo ovunque lo vogliamo?
MarceloBarbosa,

Sembra elegante. Ottimo lavoro! Tuttavia, ho notato che il sovraccarico di prototipi di base in grandi app JS (che richiedono anche test di unità) potrebbe comportare un comportamento imprevisto (vale a dire, quando si desidera iterare con "for" attraverso un array con il prototipo sovraccarico, si otterrà alcune proprietà che normalmente non ti aspetteresti). Sei stato avvertito. ;)
cassi.lup

una tua variante che accetta anche la funzione booleana StringOrElse2Bool (sob) {if (typeof sob === "string") {return ["no", "false", "0", "off"]. indexOf (sob.toLowerCase ())! == -1? falsa verità; } else {return !! sob}
bortunac il

8

Giù le mani nel modo più semplice (supponendo che la stringa sia "vera" o "falsa") è:

var z = 'true';
var y = 'false';
var b = (z === 'true'); // will evaluate to true
var c = (y === 'true'); // will evaluate to false

Usa sempre l'operatore === invece dell'operatore == per questi tipi di conversioni!


4
Di quale conversione stavi parlando? :-)
YMMD

1
Quando si confronta la stringa in javascript non vi è alcuna differenza tra l'utilizzo degli operatori == o === quando non si utilizzano le conversioni. Qui stai confrontando con le stringhe, quindi nessuna conversione di tipo. Vedere stackoverflow.com/questions/359494/...
ars265

8

Come ha detto @ Shadow2531, non puoi semplicemente convertirlo direttamente. Suggerirei anche di considerare input di stringa oltre a "true" e "false" che sono "verità" e "falsità" se il codice verrà riutilizzato / utilizzato da altri. Questo è quello che uso:

function parseBoolean(string) {
  switch (String(string).toLowerCase()) {
    case "true":
    case "1":
    case "yes":
    case "y":
      return true;
    case "false":
    case "0":
    case "no":
    case "n":
      return false;
    default:
      //you could throw an error, but 'undefined' seems a more logical reply
      return undefined;
  }
}

7

Devi separare (nel tuo pensiero) il valore delle tue selezioni e la rappresentazione di quel valore.

Scegli un punto nella logica JavaScript in cui devono passare dalle sentinelle di stringa al tipo nativo e fare un confronto lì, preferibilmente dove viene eseguito solo una volta per ogni valore che deve essere convertito. Ricorda di rispondere a ciò che deve accadere se la stringa sentinel non è quella che lo script conosce (ovvero, per impostazione predefinita, vero o falso?)

In altre parole, sì, è necessario dipendere dal valore della stringa. :-)


7

La mia opinione su questa domanda è che mira a soddisfare tre obiettivi:

  • Restituisce vero / falso per i valori di verità e falsità, ma restituisce anche vero / falso per più valori di stringa che sarebbero veritieri o falsi se fossero booleani anziché stringhe.
  • In secondo luogo, fornire un'interfaccia resiliente in modo che i valori diversi da quelli specificati non falliscano, ma piuttosto restituiscano un valore predefinito
  • Terzo, fai tutto questo con il minor codice possibile.

Il problema con l'utilizzo di JSON è che non riesce causando un errore Javascript. Questa soluzione non è resistente (sebbene soddisfi 1 e 3):

JSON.parse("FALSE") // fails

Questa soluzione non è abbastanza concisa:

if(value === "TRUE" || value === "yes" || ...) { return true; }

Sto lavorando per risolvere questo problema esatto per Typecast.js . E la migliore soluzione a tutti e tre gli obiettivi è questa:

return /^true$/i.test(v);

Funziona in molti casi, non fallisce quando vengono passati valori come {} ed è molto conciso. Inoltre restituisce false come valore predefinito anziché non definito o genera un errore, il che è più utile nello sviluppo di Javascript non tipizzato. Bravo alle altre risposte che lo hanno suggerito!


Solo per tornare ai tuoi obiettivi, l'unico problema con la tua terza e migliore soluzione è che non soddisfa l'Obiettivo n. 1 - tornerà vero solo per un valore di 'true', ma non per qualsiasi input vero. Per raggiungere l'obiettivo n. 1, è solo leggermente più conciso della soluzione n. 2 e molto meno leggibile.
JMTyler,

return /^(true|yes|1|t|y)$/i.test(str);
Kevin Boucher,

7

Sono un po 'in ritardo, ma ho un piccolo frammento per farlo, essenzialmente mantiene tutti i jutScript truthey / falsey / sudici -ma ma include "false"come valore accettabile per falso.

Preferisco questo metodo a quelli menzionati perché non si basa su una terza parte per analizzare il codice (es: eval / JSON.parse), che è eccessivo nella mia mente, è abbastanza breve da non richiedere una funzione di utilità e mantiene altre convenzioni truthey / falsey.

var value = "false";
var result = (value == "false") != Boolean(value);

// value = "true"  => result = true
// value = "false" => result = false
// value = true    => result = true
// value = false   => result = false
// value = null    => result = false
// value = []      => result = true
// etc..

7

un'altra soluzione. jsFiddle

var toBoolean = function(value) {
    var strValue = String(value).toLowerCase();
    strValue = ((!isNaN(strValue) && strValue !== '0') &&
        strValue !== '' &&
        strValue !== 'null' &&
        strValue !== 'undefined') ? '1' : strValue;
    return strValue === 'true' || strValue === '1' ? true : false
};

i casi di test vengono eseguiti nel nodo

> toBoolean(true)
true
> toBoolean(false)
false
> toBoolean(undefined)
false
> toBoolean(null)
false
> toBoolean('true')
true
> toBoolean('True')
true
> toBoolean('False')
false
> toBoolean('false')
false
> toBoolean('0')
false
> toBoolean('1')
true
> toBoolean('100')
true
> 

7

Dio santo, alcune di queste risposte sono semplicemente selvagge. Adoro JS e il suo infinito numero di modi per scuoiare un bool.

La mia preferenza, che sono rimasto scioccato di non vedere già, è:

testVar = testVar.toString().match(/^(true|[1-9][0-9]*|[0-9]*[1-9]+|yes)$/i) ? true : false;

6

Una fodera

Dobbiamo solo tenere conto della stringa "false" poiché qualsiasi altra stringa (incluso "true") è già true.

function b(v){ return v==="false" ? false : !!v; }

Test

b(true)    //true
b('true')  //true
b(false)   //false
b('false') //false

Una versione più esauriente

function bool(v){ return v==="false" || v==="null" || v==="NaN" || v==="undefined" || v==="0" ? false : !!v; }

Test

bool(true)        //true
bool("true")      //true
bool(1)           //true
bool("1")         //true
bool("hello")     //true

bool(false)       //false
bool("false")     //false
bool(0)           //false
bool("0")         //false
bool(null)        //false
bool("null")      //false
bool(NaN)         //false
bool("NaN")       //false
bool(undefined)   //false
bool("undefined") //false
bool("")          //false

bool([])          //true
bool({})          //true
bool(alert)       //true
bool(window)      //true
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.