Como posso converter uma string para booleano em JavaScript?

2553

Posso converter uma string que representa um valor booleano (por exemplo, 'true', 'false') em um tipo intrínseco em JavaScript?

Eu tenho um formulário oculto em HTML que é atualizado com base na seleção de um usuário em uma lista. Este formulário contém alguns campos que representam valores booleanos e são preenchidos dinamicamente com um valor booleano intrínseco. No entanto, quando esse valor é colocado no campo de entrada oculto, ele se torna uma sequência.

A única maneira que eu encontrei para determinar o valor booleano do campo, uma vez convertido em uma string, era depender do valor literal de sua representação em string.

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

Existe uma maneira melhor de conseguir isso?

Kevin
fonte
50
"Existe uma maneira melhor de conseguir isso?" - não é certamente uma maneira pior: Dstring=(string==String(string?true:false))?(string?true:false):(!string?true:fa‌​lse);
Mark K Cowan
3
Facilmente cordas punho e bools:function parseBool(val) { return val === true || val === "true" }
WickyNilliams
1
@Markfunction checkBool(x) { if(x) {return true;} else {return false;} }
Sebi
2
@Sebi: Você esqueceu de documentá-lo:if (checkBool(x) != false) { ... } else { ... }
Mark K Cowan
3
!!(parseInt(value) || value === "true")
Andrew Luca

Respostas:

3482

Faz:

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

Você pode torná-lo mais rígido usando o operador de identidade ( ===), que não faz nenhuma conversão implícita de tipo quando as variáveis ​​comparadas têm tipos diferentes, em vez do operador de igualdade ( ==).

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

Não faça:

Você provavelmente deve ter cuidado ao usar esses dois métodos para suas necessidades específicas:

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

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

Qualquer string que não seja a vazia será avaliada trueusando-as. Embora sejam os métodos mais limpos que posso pensar em relação à conversão booleana, acho que não são o que você está procurando.

guinaps
fonte
196
myValue === 'true';é precisamente equivalente a myValue == 'true';. Não há nenhuma vantagem em utilizar ===mais ==aqui.
Tim Down
551
Eu sigo o conselho do Crockford e uso ===e !==sempre que fizer sentido, que é quase sempre.
guinaps
55
E quanto a "TRUE" em maiúsculas, por exemplo?
BMiner 10/08/11
102
@guinaps Normalmente, sigo o conselho de Crockford, mas o cenário ==vs. ===é um dos poucos em que não. I completamente discordam que "quase sempre" faz sentido usar ===. Existem linguagens com tipos vagos, porque não queremos nos preocupar com o tipo; se verificarmos algo como if (price >= 50)se não nos importássemos se começou como uma string. Eu digo que, na maioria das vezes, queremos que tipos sejam manipulados. Nos raros casos em que não queremos malabarismo de tipos (por exemplo if (price === null)), usamos ===. Isso é o que eu faço há anos e nunca tive um problema.
JMTyler #
169
O @JMTyler pode estar ignorando o programador de manutenção que vem depois. Sempre use o operador de comparação adequado! Se você conhece 'com certeza' os tipos de ambos os lados, mas não usa ===, não terei esse conhecimento ao analisar seu código posteriormente. Se seu código for reutilizado, isso pode se tornar um pesadelo. Se você REALMENTE quiser que seus tipos sejam 'malabarismos' como você diz, use '==', mas muitos desenvolvedores JS trarão isso com muita facilidade, melhor para reforçar seu código. Com que frequência desejo que a string 'false' signifique booleano 'true'?
aikeru
687

Atenção

Essa resposta herdada altamente votada é tecnicamente correta, mas cobre apenas um cenário muito específico, quando o valor da string é EXATAMENTE "true"ou"false" .

Uma string json inválida passada para essas funções abaixo lançará uma exceção .


Resposta original:

E se?

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

ou com jQuery

$.parseJSON("TRUE".toLowerCase());
Luke
fonte
62
O problema é que muitos valores potenciais geram um erro de análise que interrompe a execução do JS. Então, a execução do JSON.parse ("FALSE") bombeia o Javascript. Penso que o objetivo da questão não é simplesmente resolver esses casos exatos, mas também ser resiliente a outros casos.
precisa saber é o seguinte
3
@ Lucas, esta solução é exatamente o que eu precisava; bem, envolvê-lo em uma tentativa ... pegar embora. Eu queria converter para booleano apenas se fosse um valor booleano na string; caso contrário, basta usar a string fornecida. Isso funciona! Obrigado.
jedmao
47
É muito simples dizer apenas JSON.parse("TRUE".toLowerCase())para que ele possa analisar corretamente.
Yuck
27
por que existem tantos votos positivos? Isso é ineficiente e horrível. O que vem a seguir? '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// só para ter certeza
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);
    }
}
Steven
fonte
43
Na verdade, pode ser simplificado. 1) Não há nenhuma necessidade para testar "true", "yes"e "1". 2) toLowerCasenão retorna null. 3) Boolean(string)é o mesmo que string!==""aqui. =>switch(string.toLowerCase()) {case "false": case "no": case "0": case "": return false; default: return true;}
Robert
15
@ Robert, um bom, mas eu prefiro ter o padrão como alternativa false.
Drigoangelo 21/10
@drigoangelo Ter default: return true;é certamente possível. Mas isso mudaria o comportamento da função.
Robert
2
Eu pensei que esta era a melhor resposta, e quis elaborar sobre isso aqui: stackoverflow.com/questions/263965/...
BrDaHa
9
se você estiver de dados normalização chamando .toLowerCase (), então você mightt quer jogar na guarnição () para retirar espaço em branco bem
jCuga
174

Eu acho que isso é muito universal:

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

Vai:

String(true) == "true"     //returns true
String(false) == "true"    //returns false
String("true") == "true"   //returns true
String("false") == "true"  //returns false
ander
fonte
20
Quando você pode receber uma string em letras maiúsculas ou um booleano, entãoString(a).toLowerCase() === 'true'
pauloya
String("what about input like this that isn't a bool?") == "true"
Thomas Eding
6
@ThomasEding false ... o que você quer que ele retorne?
Snowburnt 25/10
2
pode até encurtar ao não usar o String()construtor:true+'' === 'true' // true
Todd
1
BTW, para 1 ou 0 também deve lançar para falso ou verdadeiro
Miguel
128

Lembre-se de combinar o caso:

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

Além disso, se for uma caixa de seleção de elemento de formulário, você também poderá detectar se a caixa de seleção está marcada:

var isTrueSet = document.myForm.IS_TRUE.checked;

Supondo que, se marcado, ele é "definido" igual a verdadeiro. Isso é avaliado como verdadeiro / falso.

Jared Farrish
fonte
3
Isto irá lançar uma exceção se myValuepassa a ser null, trueou algum outro tipo ...
mik01aj
116

Você pode usar expressões regulares:

/*
 * 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 você gosta de estender a classe String, pode fazer:

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

alert("true".bool());

Para aqueles (veja os comentários) que gostariam de estender o objeto String para obter isso, mas estão preocupados com a enumerabilidade e estão preocupados com o conflito com outro código que estende o objeto String:

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

(Não funciona em navegadores antigos, é claro, e o Firefox mostra falso, enquanto o Opera, Chrome, Safari e IE mostram verdadeiro. Bug 720760 )

shrewmouse
fonte
10
Você sempre pode prefixar a função se tiver medo de que ela interfira em algum outro código. Se algum código ainda quebrar, esse código é muito frágil e deve ser corrigido. Se sua função adicionada torna o objeto muito pesado, causando um problema de desempenho para outro código, obviamente você não deseja fazer isso. Mas, geralmente, não é uma má idéia estender objetos internos. Eles também não seriam publicamente extensíveis se esse fosse o caso.
Shadow2531
41
@DTrejo @Szymon Eu discordo. Esse é exatamente o tipo de coisa que sobrecarrega o protótipo. Se você tem medo de quebrar o código (ruim) que se baseia em for..in, existem maneiras de ocultar as propriedades da enumeração. Veja Object.defineProperty.
devios1
Para seguir a convenção eu chamaria #parseBool
guzart
8
A análise booleana não pertence à classe String. Você acabaria com qualquer quantidade de analisadores de lixo e conversão lá. -1 para alterar protótipos em geral. -1 para soluções que não funcionam entre navegadores. -1 para design deficiente.
21412 Thomas Thomas W
1
Aqui está uma comparação de desempenho de todas as respostas. stackoverflow.com/a/28588344/2824333
sospedra
50

Olho de madeira tenha cuidado. Depois de ver as consequências depois de aplicar a resposta principal com mais de 500 upvotes, sinto-me obrigado a postar algo que é realmente útil:

Vamos começar da maneira mais curta, mas muito rigorosa:

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

E termine com uma maneira adequada e mais tolerante:

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;
}

Teste:

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]));}
Stefan Steiger
fonte
Lembre-se de que navegadores mais antigos podem precisar de um polyfill JSON se você usar o primeiro método.
DRahal #
1
Qual é a velocidade de conversão da string "false" para o falsevalor booleano JSON.parse? Em termos de CPU, desempenho da memória
Verde
Não seria mais fácil começar com if (str) {...} para eliminar tudo o que já é falso? E dentro dessa condição if, basta se preocupar em retornar true, porque você já termina com return false!
Larphoid 01/12/19
Lembre-se de que você pode reduzir muitos dos testes de string com (["true", "yes", "1"]. IndexOf (str.toLowerCase (). Trim ())! = -1) e usar um fallback de Boolean (str) para cobrir coisas como 'null'
Scott
38

Eu pensei que a resposta de @Steven era a melhor e resolvi muito mais casos do que se o valor recebido fosse apenas uma string. Eu queria estender um pouco e oferecer o seguinte:

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;
    }
}

Não é necessário cobrir todo o false casos, se você já conhece todos os truecasos que precisaria considerar. Você pode passar qualquer coisa para esse método que possa passar por um truevalor (ou adicionar outros, é bem direto), e todo o resto seria consideradofalse

BrDaHa
fonte
Eu uso este, pois abrange coisas que você começa a partir de XML / HTML ElementNodes atributos comoautocomplete="on"
philk
2
Eu acrescentaria .trim () antes toLowerCase ()
Luis Lobo Borobia
34

Solução universal com análise 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

ATUALIZAÇÃO (sem JSON):

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

Eu também criei o violino para testá-lo http://jsfiddle.net/remunda/2GRhG/

Jan Remunda
fonte
1
A versão 'sem JSON' tem alguma falha: val = "0"; console.log (!! (+ val || String (val) .toLowerCase (). replace (!! 0, ''))); produz true
Etienne
3
getBool(undefined)falhará Ao usar a versão JSON original e retornará true para a 2ª versão. Aqui está uma terceira versão que retorna false: function getBool (val) {var num; return val! = null && (! isNaN (num = + val)? !! num: !! String (val) .toLowerCase (). replace (!! 0, '')); }
Ron Martinez
31

Sua solução está boa.

Usar ===seria tolo nesse caso, pois o campo valuesempre será umString .

Jonny Buchanan
fonte
17
Por que você acha que seria bobo de usar ===? Em termos de desempenho, seria exatamente o mesmo se os dois tipos fossem Strings. Enfim, prefiro usar, ===pois sempre evito o uso de ==e !=. Justificativas: stackoverflow.com/questions/359494/…
Mariano Desanze
3
Desde valuesempre será um stringnem ==nem ===são tolas. Ambos são a ferramenta certa para este trabalho. Eles diferem apenas quando os tipos não são iguais. Nesse caso, ===simplesmente retorna falseenquanto ==executa um algoritmo de coerção de tipo intrincado antes da comparação.
Robert
23
var falsy = /^(?:f(?:alse)?|no?|0+)$/i;
Boolean.parse = function(val) { 
    return !falsy.test(val) && !!val;
};

Isso retorna falsepara cada valor Falsas e truepara cada valor truthy exceto para '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());
Prestaul
fonte
20

O objeto booleano não possui um método de 'análise'. Boolean('false')retorna true, para que não funcione. !!'false'também retorna true, para que não funcione também.

Se você deseja que a string 'true'retorne booleano truee a string 'false'retorne booleano false, a solução mais simples é usar eval(). eval('true')retorna verdadeiro e eval('false')retorna falso. Lembre-se das implicações de desempenho ao usá-lo eval().

10basetom
fonte
Para entender o que há de "errado" (ou certo) com o eval - consulte artigos como javascriptweblog.wordpress.com/2010/04/19/how-evil-is-eval ou pesquise no stackoverflow por 'Javascript eval malware'
GrahamMc
2
Concordo que var isTrueSet = (myValue === 'true');é a melhor resposta.
thdoan
Eu gosto que seja conciso. Mas falha espetacularmente no caso básico de eval('TRUE'); provar mais uma vez, isso eval()é mau.
Snowman
@Area 51 Detective Fiction, da mesma maneira, JSON.parse('TRUE')da resposta abaixo também falha espetacularmente. É muito fácil forçar uma condição de erro no JavaScript (ou em qualquer outro idioma). Para conta para isso, você deve normalizar a corda primeiro, por exemplo,var myValue = document.myForm.IS_TRUE.value.toLowerCase(); var isTrueSet = (myValue==='true' || myValue==='false') ? eval(myValue) : false;
thdoan
1
@ 10basetom: Muito correto. Você deve incluir .toLowerCase()na resposta é o meu ponto. Não estou tentando forçar nada. Maiúsculas TRUEé um valor bastante comum para ser retornado por muitos widgets da UI.
Snowman
18

Isso foi retirado da resposta aceita, mas na verdade tem um ponto muito fraco, e estou chocado com a quantidade de votos positivos, o problema com o qual você deve considerar o caso da string, porque isso diferencia maiúsculas de minúsculas

var isTrueSet = (myValue.toLowerCase() === 'true');
Hakam Fostok
fonte
16

Eu uso o seguinte:

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

Essa função executa a coerção booleana usual, com exceção das seqüências de caracteres "false" (sem distinção entre maiúsculas e minúsculas) e "0".

zobier
fonte
16

Há muitas respostas e é difícil escolher uma. No meu caso, priorizo ​​o desempenho ao escolher, então crio esse jsPerf que espero que possa trazer alguma luz aqui.

Resumo dos resultados (quanto maior, melhor):

  1. Declaração condicional : 2.826.922
  2. Alternar maiúsculas e minúsculas no objeto Bool : 2.825.469
  3. Transmitindo para JSON : 1.867.774
  4. !! conversões : 805,322
  5. Protótipo de sequência: 713,637

Eles estão vinculados à resposta relacionada, onde você pode encontrar mais informações (prós e contras) sobre cada um; especialmente nos comentários.

sospedra
fonte
"alguma coisa deu errado" ao tentar visualizar teste JSPerf
spottedmahn
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.");
  }
};
Thomas Eding
fonte
2
Você pode usar true.toString () em vez de "true" para ser ainda mais limpo :-)
tillda
Não altere globals, tente manter as suas alterações isolado, talvez criar um novo function parseBooleanem vez
Aço Cérebro
13

A expressão que você procura simplesmente é

/^true$/i.test(myValue)

como em

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

Isso testa myValue uma expressão regular, que não diferencia maiúsculas de minúsculas e não modifica o protótipo.

Exemplos:

/^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
AndreasPizsa
fonte
12

Para converter string ("true", "false") e booleano em booleano

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

Onde flagpode estar

 var flag = true
 var flag = "true"
 var flag = false
 var flag = "false"
Fizer Khan
fonte
12

Já existem muitas respostas disponíveis. Mas seguir pode ser útil em alguns cenários.

// 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;
    });
}

Isso pode ser útil onde exemplos com valores não booleanos.

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

getBoolean('true'); // true
getBoolean(true); // true
getBoolean(1); // true
Sandip Nirmal
fonte
10

por que você não tenta algo assim

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

Ele retornará um erro quando algum outro texto for fornecido, em vez de verdadeiro ou falso, independentemente do caso, e capturará os números também como

// 0-> false
// any other number -> true
Yohan
fonte
10

Esta função pode lidar com strings e também com Boolean true / false.

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

Demonstração abaixo:

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)));

user1063287
fonte
9

Eu estou usando esse

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"
Adam Pietrasiak
fonte
Isso é bom, mas funciona apenas com o tipo String. Imagine que isso precise ser usado por uma variável que seja talvez "true"ou true. Se vier o segundo, isso não funcionará. É possível fazer isso document.prototypepara usar onde quisermos?
MarceloBarbosa
Isso parece elegante. Bom trabalho! No entanto, notei que a sobrecarga de protótipos básicos em aplicativos JS grandes (que também precisam de teste de unidade) pode resultar em um comportamento inesperado (ou seja, quando você deseja iterar com "for" por meio de uma matriz com o protótipo sobrecarregado, você obtém algumas propriedades que você normalmente não esperaria). Você foi avisado. ;)
cassi.lup 11/03/2015
uma variante sua que também aceita a função booleana StringOrElse2Bool (sob) {if (typeof sob === "string") {return ["no", "false", "0", "off"]. indexOf (sob.toLowerCase ())! == -1? falso verdadeiro; } else {return !! sob}
bortunac
8

De maneira geral, a maneira mais fácil (assumindo que sua string será 'true' ou 'false') é:

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

Sempre use o operador === em vez do operador == para esses tipos de conversões!

subida
fonte
4
De que conversão você estava falando? :-)
YMMD
1
Ao comparar string em javascript, não há diferença entre usar os operadores == ou === quando não estiver usando conversões. Aqui você está comparando com strings, portanto, sem conversões de tipo. Veja stackoverflow.com/questions/359494/…
ars265
8

Como @ Shadow2531 disse, você não pode simplesmente convertê-lo diretamente. Eu também sugiro que você considere as entradas de string além de "true" e "false" que são 'verdade' e 'falsey' se o seu código for reutilizado / usado por outras pessoas. Isto é o que eu 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;
  }
}
imjustmatthew
fonte
7

Você precisa separar (em sua opinião) o valor de suas seleções e a representação desse valor.

Escolha um ponto na lógica JavaScript em que eles precisam fazer a transição dos sentinelas de seqüência de caracteres para o tipo nativo e faça uma comparação lá, preferencialmente onde isso é feito apenas uma vez para cada valor que precisa ser convertido. Lembre-se de abordar o que precisa acontecer se a string sentinel não for a que o script conhece (por exemplo, você usa true ou false?)

Em outras palavras, sim, você precisa depender do valor da string. :-)

staticsan
fonte
7

Minha opinião sobre esta questão é que ela visa satisfazer três objetivos:

  • Retorne true / false para valores truthy e falsey, mas também retorne true / false para vários valores de string que seriam truthy ou falsey se fossem booleanos em vez de strings.
  • Segundo, forneça uma interface resiliente para que valores diferentes dos especificados não falhem, mas retorne um valor padrão
  • Terceiro, faça tudo isso com o mínimo de código possível.

O problema com o uso de JSON é que ele falha ao causar um erro de Javascript. Esta solução não é resiliente (embora satisfaça 1 e 3):

JSON.parse("FALSE") // fails

Esta solução não é concisa o suficiente:

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

Estou trabalhando para resolver esse problema exato do Typecast.js . E a melhor solução para todos os três objetivos é esta:

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

Funciona para muitos casos, não falha quando valores como {} são passados ​​e é muito conciso. Além disso, ele retorna false como o valor padrão, em vez de indefinir ou lançar um erro, o que é mais útil no desenvolvimento de Javascript de baixa digitação. Bravo para as outras respostas que sugeriram!

BishopZ
fonte
Apenas para voltar aos seus objetivos, o único problema com sua terceira e melhor solução é que ela não atende ao objetivo nº 1 - retornará verdadeiro apenas para um valor de 'true', mas não para qualquer entrada de verdade . Para fazer com que ele atinja o objetivo nº 1, é apenas um pouco mais conciso que a solução nº 2 e muito menos legível.
JMTyler #
return /^(true|yes|1|t|y)$/i.test(str);
21716 Kevin Kevin Boucher
7

Estou um pouco atrasado, mas tenho um pequeno trecho para fazer isso, ele essencialmente mantém todos os JScripts verdadeiros / falsos / imundos, mas inclui "false"como um valor aceitável para falso.

Prefiro esse método aos mencionados, porque não depende de terceiros para analisar o código (por exemplo: eval / JSON.parse), que é um exagero em minha mente, é curto o suficiente para não exigir uma função de utilitário e mantém outras convenções de 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..
Dead.Rabit
fonte
7

outra solução. 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
};

casos de teste executados no nó

> 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
> 
vbranden
fonte
7

Santo Deus, algumas dessas respostas são simplesmente selvagens. Eu amo JS e seu número infinito de maneiras de criar um bool.

Minha preferência, que fiquei chocado ao não ver, é:

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

One Liner

Nós apenas precisamos considerar a string "false", já que qualquer outra string (incluindo "true") já é true.

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

Teste

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

Uma versão mais exaustiva

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

Teste

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
Vitim.us
fonte