Comment puis-je convertir une chaîne en booléen en JavaScript?

2556

Puis-je convertir une chaîne représentant une valeur booléenne (par exemple, "vrai", "faux") en un type intrinsèque en JavaScript?

J'ai un formulaire caché en HTML qui est mis à jour en fonction de la sélection d'un utilisateur dans une liste. Ce formulaire contient certains champs qui représentent des valeurs booléennes et sont remplis dynamiquement avec une valeur booléenne intrinsèque. Cependant, une fois que cette valeur est placée dans le champ de saisie masqué, elle devient une chaîne.

Le seul moyen que j'ai pu trouver pour déterminer la valeur booléenne du champ, une fois qu'il a été converti en chaîne, était de dépendre de la valeur littérale de sa représentation sous forme de chaîne.

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

Existe-t-il une meilleure façon d'accomplir cela?

Kevin
la source
50
"Y a-t-il une meilleure façon d'accomplir cela?" - il y a certainement pire: Dstring=(string==String(string?true:false))?(string?true:false):(!string?true:fa‌​lse);
Mark K Cowan
3
Manipulez facilement les cordes et les bools:function parseBool(val) { return val === true || val === "true" }
WickyNilliams
1
@Markfunction checkBool(x) { if(x) {return true;} else {return false;} }
Sebi
2
@Sebi: Vous avez oublié de le documenter:if (checkBool(x) != false) { ... } else { ... }
Mark K Cowan
3
!!(parseInt(value) || value === "true")
Andrew Luca

Réponses:

3483

Faire:

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

Vous pouvez le rendre plus strict en utilisant l'opérateur d'identité ( ===), qui n'effectue aucune conversion de type implicite lorsque les variables comparées ont des types différents, au lieu de l'opérateur d'égalité ( ==).

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

Ne pas:

Vous devriez probablement être prudent lorsque vous utilisez ces deux méthodes pour vos besoins spécifiques:

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

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

Toute chaîne qui n'est pas la chaîne vide sera évaluée trueen les utilisant. Bien que ce soient les méthodes les plus propres auxquelles je puisse penser en ce qui concerne la conversion booléenne, je pense que ce n'est pas ce que vous recherchez.

guinaps
la source
196
myValue === 'true';est précisément équivalent à myValue == 'true';. Il n'y a aucun avantage à utiliser ===plus ==ici.
Tim Down
551
Je suis les conseils et l'utilisation de Crockford=== et !==chaque fois que cela a du sens, ce qui est presque toujours le cas.
guinaps
55
Qu'en est-il de "VRAI" en majuscules, par exemple?
BMiner
102
@guinaps J'ai l'habitude de suivre les conseils de Crockford, mais le scénario ==vs ===est l'un des rares où je ne le fais pas. Je ne suis pas du tout d' accord pour dire qu'il est «presque toujours» judicieux d'utiliser ===. Des langages mal typés existent parce que nous ne voulons pas nous soucier du type; si nous vérifions quelque chose comme if (price >= 50)nous ne nous soucions pas si cela a commencé comme une chaîne. Je dis, la plupart du temps, nous voulons que les types soient jonglés. Dans les rares cas où nous ne voulons pas jongler avec le type (par exemple if (price === null)), nous utilisons ===. C'est ce que je fais depuis des années et je n'ai jamais eu de problème.
JMTyler
169
@JMTyler pourrait ignorer le programmeur de maintenance à venir. Utilisez toujours l'opérateur de comparaison approprié! Si vous connaissez «à coup sûr» les types des deux côtés, mais n'utilisez pas ===, je n'aurai pas cette connaissance en regardant votre code plus tard. Si votre code est réutilisé, cela peut devenir un cauchemar. Si vous voulez VRAIMENT que vos types soient "jonglés" comme vous le dites, alors utilisez "==", mais trop de développeurs JS se déclencheront trop facilement, mieux vaut resserrer votre code. Combien de fois est-ce que je veux que la chaîne "false" signifie booléen "true"?
aikeru
687

Attention

Cette réponse héritée très appréciée est techniquement correcte mais ne couvre qu'un scénario très spécifique, lorsque la valeur de votre chaîne est EXACTEMENT "true"ou "false".

Une chaîne json non valide passée dans ces fonctions ci-dessous lèvera une exception .


Réponse originale:

Que diriez-vous?

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

ou avec jQuery

$.parseJSON("TRUE".toLowerCase());
Luke
la source
62
Le problème est que de nombreuses valeurs potentielles génèrent une erreur d'analyse qui arrête l'exécution de JS. Donc, exécuter JSON.parse ("FALSE") bombarde Javascript. Le point de la question, je pense, n'est pas simplement de résoudre ces cas précis, mais aussi d'être résilient à d'autres cas.
BishopZ
3
@Luke, cette solution est exactement ce dont j'avais besoin; eh bien, enveloppez-le dans un essai ... attrapez bien. Je voulais convertir en bool uniquement si c'était une valeur booléenne dans la chaîne; sinon, utilisez simplement la chaîne fournie. Cela marche! Merci.
jedmao
47
C'est assez simple à dire JSON.parse("TRUE".toLowerCase())pour qu'il puisse analyser correctement.
Beurk
27
pourquoi il y a tant de votes positifs? C'est inefficace et horrible. '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// juste pour être sûr
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
la source
43
En fait, cela peut être simplifié. 1) Il n'est pas nécessaire de tester "true", "yes"et "1". 2) toLowerCasene revient pas null. 3) Boolean(string)est le même string!==""qu'ici. =>switch(string.toLowerCase()) {case "false": case "no": case "0": case "": return false; default: return true;}
Robert
15
@Robert, sympa, mais je préfère avoir la valeur par défaut comme false.
drigoangelo
@drigoangelo Avoir default: return true;est certainement possible. Mais cela changerait le comportement de la fonction.
Robert
2
Je pensais que c'était la meilleure réponse et je voulais en
parler
9
si vous normalisez des données en appelant .toLowerCase (), alors vous voudrez peut-être aussi
ajouter
174

Je pense que c'est beaucoup universel:

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

Ça va:

String(true) == "true"     //returns true
String(false) == "true"    //returns false
String("true") == "true"   //returns true
String("false") == "true"  //returns false
ander
la source
20
Lorsque vous pouvez recevoir une chaîne en majuscules ou en booléen, alorsString(a).toLowerCase() === 'true'
pauloya
String("what about input like this that isn't a bool?") == "true"
Thomas Eding
6
@ThomasEding false ... que voulez-vous qu'il retourne?
Snowburnt
2
pourrait même raccourcir en n'utilisant pas le String()constructeur:true+'' === 'true' // true
Todd
1
BTW, pour 1 ou 0, il devrait également lancer pour faux ou vrai
Miguel
128

N'oubliez pas de faire correspondre la casse:

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

De plus, s'il s'agit d'une case à cocher d'élément de formulaire, vous pouvez également détecter si la case est cochée:

var isTrueSet = document.myForm.IS_TRUE.checked;

En supposant que s'il est coché, il est "défini" égal à vrai. Ceci est évalué comme vrai / faux.

Jared Farrish
la source
3
Cela lèvera une exception s'il myValuese trouve null, trueou un autre type ...
mik01aj
116

Vous pouvez utiliser des expressions régulières:

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

Si vous aimez étendre la classe String, vous pouvez faire:

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

alert("true".bool());

Pour ceux (voir les commentaires) qui souhaitent étendre l'objet String pour l'obtenir, mais s'inquiètent de l'énumération et craignent de se heurter à un autre code qui étend l'objet String:

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

(Ne fonctionnera pas dans les anciens navigateurs bien sûr et Firefox affiche faux alors qu'Opera, Chrome, Safari et IE sont vrais. Bogue 720760 )

musaraigne
la source
10
Vous pouvez toujours préfixer la fonction si vous craignez qu'elle n'interfère avec un autre code. Si du code se casse toujours, ce code est tout simplement trop fragile et doit être corrigé. Si votre fonction ajoutée rend l'objet trop lourd là où il cause un problème de performances pour un autre code, alors, évidemment, vous ne voulez pas le faire. Mais, je ne pense pas que ce soit généralement une mauvaise idée d'étendre des objets intégrés. Ils ne seraient pas non plus publiquement extensibles si tel était le cas.
Shadow2531
41
@DTrejo @Szymon Je ne suis pas d'accord. C'est exactement le genre de chose pour laquelle le prototype est surchargé. Si vous avez peur qu'il casse un code (pauvre) qui dépend de for..in, il existe des moyens de masquer les propriétés de l'énumération. Tu vois Object.defineProperty.
devios1
Pour suivre la convention, je l'appelleraisparseBool
guzart
8
L'analyse booléenne n'appartient pas à la classe String .. vous vous retrouveriez avec n'importe quelle quantité d'analyseurs de déchets et de conversion là-bas. -1 aux prototypes changeants en général. -1 aux solutions qui ne fonctionnent pas sur plusieurs navigateurs. -1 pour une mauvaise conception.
Thomas W
1
Voici une comparaison des performances de toutes les réponses. stackoverflow.com/a/28588344/2824333
sospedra
50

Wood-eye, soyez prudent. Après avoir vu les conséquences après avoir appliqué la première réponse avec plus de 500 votes positifs, je me sens obligé de publier quelque chose qui est réellement utile:

Commençons par le moyen le plus court mais le plus strict:

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

Et terminez d'une manière appropriée et plus tolérante:

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

Essai:

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
la source
N'oubliez pas que les anciens navigateurs peuvent avoir besoin d'un polyfill JSON si vous utilisez la première méthode.
DRaehal
1
Quelle est la vitesse de conversion de "fausse" chaîne en falsevaleur booléenne avec JSON.parse? En termes de CPU, de performances mémoire
Vert
Ne serait-il pas plus facile de commencer par if (str) {...} pour éliminer tout ce qui est déjà faux? Et à l'intérieur de cette condition if, il suffit de s'inquiéter de retourner true, car vous finissez déjà avec return false!
Larphoid
Gardez à l'esprit que vous pouvez raccourcir de nombreux tests de chaîne avec (["true", "yes", "1"]. IndexOf (str.toLowerCase (). Trim ())! = -1) et utiliser une solution de secours de Boolean (str) pour couvrir des choses comme 'null'
Scott
38

J'ai pensé que la réponse de @Steven était la meilleure et j'ai pris en charge beaucoup plus de cas que si la valeur entrante n'était qu'une chaîne. Je voulais l'étendre un peu et offrir ce qui suit:

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

Il n'est pas nécessaire de couvrir tous les falsecas si vous connaissez déjà tous les truecas dont vous auriez à rendre compte. Vous pouvez passer n'importe quoi dans cette méthode qui pourrait passer pour une truevaleur (ou en ajouter d'autres, c'est assez simple), et tout le reste serait considéréfalse

BrDaHa
la source
J'utilise celui-ci car il couvre les choses que vous obtenez des attributs XML / HTML autocomplete="on"
ElementNodes
2
J'ajouterais .trim () avant toLowerCase ()
Luis Lobo Borobia
34

Solution universelle avec analyse 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

MISE À JOUR (sans JSON):

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

J'ai aussi créé du violon pour le tester http://jsfiddle.net/remunda/2GRhG/

Jan Remunda
la source
1
La version 'sans JSON' a un défaut: val = "0"; console.log (!! (+ val || String (val) .toLowerCase (). replace (!! 0, ''))); produit vrai
Etienne
3
getBool(undefined)plantera lors de l'utilisation de la version JSON d'origine et retournera vrai pour la 2ème version. Voici une 3ème version qui retourne false: function getBool (val) {var num; return val! = null && (! isNaN (num = + val)? !! num: !! String (val) .toLowerCase (). replace (!! 0, '')); }
Ron Martinez
31

Votre solution est très bien.

L'utilisation ===serait juste idiote dans ce cas, car le champ valuesera toujours a String.

Jonny Buchanan
la source
17
Pourquoi pensez-vous que ce serait stupide à utiliser ===? En termes de performances, ce serait exactement la même chose si les deux types sont des chaînes. Quoi qu'il en soit, je préfère utiliser ===car j'évite toujours l'utilisation de ==et !=. Justifications: stackoverflow.com/questions/359494/…
Mariano Desanze
3
Depuis valuesera toujours un stringni ==ni ===stupide. Les deux sont le bon outil pour ce travail. Ils ne diffèrent que lorsque les types ne sont pas égaux. Dans ce cas, ===renvoie simplement falsewhile ==exécute un algorithme de coercition de type complexe avant la comparaison.
Robert
23
var falsy = /^(?:f(?:alse)?|no?|0+)$/i;
Boolean.parse = function(val) { 
    return !falsy.test(val) && !!val;
};

Ce rendement falsepour chaque valeur falsy et truepour chaque valeur de truthy sauf pour 'false', 'f', 'no', 'n'et '0'(insensible à la casse).

// 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
la source
20

L'objet booléen n'a pas de méthode 'parse'. Boolean('false')renvoie vrai, donc cela ne fonctionnera pas. !!'false'revient également true, de sorte que cela ne fonctionnera pas également.

Si vous souhaitez que chaîne 'true'renvoie un booléen trueet chaîne 'false'pour renvoyer un booléen false, la solution la plus simple consiste à utiliser eval(). eval('true')renvoie vrai et eval('false')renvoie faux. Gardez à l'esprit les implications en termes de performances lors de l'utilisation eval().

10basetom
la source
Pour comprendre ce qui est "mal" (ou bien) avec eval - consultez des articles comme javascriptweblog.wordpress.com/2010/04/19/how-evil-is-eval ou recherchez sur stackoverflow pour 'Javascript eval malware'
GrahamMc
2
Je suis d'accord que var isTrueSet = (myValue === 'true');c'est la meilleure réponse.
thdoan
J'aime que ce soit concis. Mais il échoue de façon spectaculaire pour le cas de base de eval('TRUE'); prouvant une fois de plus, c'est eval()mal.
Bonhomme de neige
@Area 51 Detective Fiction, de la même manière, JSON.parse('TRUE')de la réponse ci-dessous échoue également de manière spectaculaire. Il est assez facile de forcer une condition d'erreur en JavaScript (ou dans n'importe quelle langue, d'ailleurs). Pour tenir compte de cela, vous devez d'abord normaliser la chaîne, par exemple,var myValue = document.myForm.IS_TRUE.value.toLowerCase(); var isTrueSet = (myValue==='true' || myValue==='false') ? eval(myValue) : false;
thdoan
1
@ 10basetom: Tout à fait correct. Vous devriez inclure .toLowerCase()dans la réponse est mon point. Je n'essaye pas de forcer quoi que ce soit. Les majuscules TRUEsont une valeur suffisamment courante pour être renvoyée par de nombreux widgets d'interface utilisateur.
Snowman
18

Cela a été tiré de la réponse acceptée, mais en réalité, il a un point très faible, et je suis choqué de voir comment il a obtenu ce nombre de votes positifs, le problème avec cela, c'est que vous devez considérer le cas de la chaîne car il est sensible à la casse

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

J'utilise ce qui suit:

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

Cette fonction effectue la contrainte booléenne habituelle à l'exception des chaînes "false" (insensible à la casse) et "0".

zobier
la source
16

Il y a beaucoup de réponses et il est difficile d'en choisir une. Dans mon cas, je priorise les performances lors du choix, donc je crée ce jsPerf qui, je l'espère, pourra apporter un peu de lumière ici.

Bref des résultats (le plus haut sera le mieux):

  1. Déclaration conditionnelle : 2 826 922
  2. Boîtier de commutateur sur objet Bool : 2 825 469
  3. Casting en JSON : 1 867 774
  4. !! conversions : 805 322
  5. Prototype de chaîne : 713 637

Ils sont liés à la réponse correspondante où vous pouvez trouver plus d'informations (avantages et inconvénients) sur chacun d'eux; spécialement dans les commentaires.

sospedra
la source
"quelque chose s'est mal passé" en essayant de voir le 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.");
  }
};
Thomas Eding
la source
2
Vous pouvez utiliser true.toString () au lieu de "true" pour être encore plus propre :-)
tillda
Ne changez pas les globaux, essayez de garder vos changements isolés, créez peut-être un nouveau à la function parseBooleanplace
Steel Brain
13

L'expression que vous recherchez est simplement

/^true$/i.test(myValue)

un péché

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

Cela teste myValueune expression régulière, insensible à la casse et ne modifie pas le prototype.

Exemples:

/^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
la source
12

Pour convertir à la fois une chaîne ("vrai", "faux") et un booléen en booléen

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

flagpeut être

 var flag = true
 var flag = "true"
 var flag = false
 var flag = "false"
Fizer Khan
la source
12

Il y a déjà tellement de réponses disponibles. Mais ce qui suit peut être utile dans certains scénarios.

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

Cela peut être utile lorsqu'un exemple avec des valeurs non booléennes.

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

getBoolean('true'); // true
getBoolean(true); // true
getBoolean(1); // true
Sandip Nirmal
la source
10

pourquoi n'essayez-vous pas quelque chose comme ça

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

Il retournera une erreur lorsqu'un autre texte est donné plutôt que vrai ou faux quel que soit le cas et il capturera également les nombres comme

// 0-> false
// any other number -> true
Yohan
la source
10

Cette fonction peut gérer les chaînes ainsi que les valeurs booléennes true / false.

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

Démonstration ci-dessous:

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

utilisateur1063287
la source
9

J'utilise celui-ci

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
la source
C'est bien, mais cela ne fonctionne qu'avec le type String. Imaginez que cela doive être utilisé par une variable qui est peut-être "true"ou true. Si vient le second, cela ne fonctionnera pas. Est-il possible de faire un document.prototypepour l'utiliser où nous le voulons?
MarceloBarbosa
Cela a l'air élégant. Bon travail! Cependant, j'ai remarqué que la surcharge des prototypes de base dans les grandes applications JS (qui ont également besoin de tests unitaires) peut entraîner un comportement inattendu (à savoir, lorsque vous souhaitez répéter avec "pour" à travers un tableau dont le prototype est surchargé, vous obtiendrez certaines propriétés que vous ne vous attendez pas normalement). Tu étais prévenu. ;)
cassi.lup
une variante de la vôtre qui accepte aussi la fonction booléenne StringOrElse2Bool (sob) {if (typeof sob === "string") {return ["no", "false", "0", "off"]. indexOf (sob.toLowerCase ())! == -1? faux vrai; } else {return !!
sob

8

De loin, le moyen le plus simple (en supposant que votre chaîne soit «vraie» ou «fausse») est:

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

Utilisez toujours l'opérateur === au lieu de l'opérateur == pour ces types de conversions!


4
De quelle conversion parliez-vous? :-)
YMMD

1
Lorsque vous comparez une chaîne en javascript, il n'y a aucune différence entre l'utilisation des opérateurs == ou === lorsque vous n'utilisez pas de conversions. Ici, vous comparez à des chaînes, donc aucune conversion de type. Voir stackoverflow.com/questions/359494/…
ars265

8

Comme l'a dit @ Shadow2531, vous ne pouvez pas simplement le convertir directement. Je suggérerais également que vous considériez les entrées de chaîne en plus de "vrai" et "faux" qui sont "véridiques" et "falsey" si votre code va être réutilisé / utilisé par d'autres. Voici ce que j'utilise:

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

Vous devez séparer (dans votre réflexion) la valeur de vos sélections et la représentation de cette valeur.

Choisissez un point dans la logique JavaScript où ils doivent passer des sentinelles de chaîne au type natif et faites une comparaison là-bas, de préférence où cela n'est fait qu'une seule fois pour chaque valeur à convertir. N'oubliez pas de répondre à ce qui doit se produire si la chaîne sentinelle n'est pas celle que le script connaît (c.-à-d. Est-ce que vous par défaut est vrai ou faux?)

En d'autres termes, oui, vous devez dépendre de la valeur de la chaîne. :-)


7

Mon point de vue sur cette question est qu'elle vise à satisfaire trois objectifs:

  • Renvoie true / false pour les valeurs truey et falsey, mais renvoie également true / false pour les valeurs de chaîne multiples qui seraient véridiques ou falsey s'il s'agissait de booléens au lieu de chaînes.
  • Deuxièmement, fournissez une interface résiliente afin que des valeurs autres que celles spécifiées n'échouent pas, mais renvoient plutôt une valeur par défaut
  • Troisièmement, faites tout cela avec le moins de code possible.

Le problème avec l'utilisation de JSON est qu'il échoue en provoquant une erreur Javascript. Cette solution n'est pas résiliente (bien qu'elle satisfasse 1 et 3):

JSON.parse("FALSE") // fails

Cette solution n'est pas assez concise:

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

Je travaille sur la résolution de ce problème exact pour Typecast.js . Et la meilleure solution à ces trois objectifs est celle-ci:

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

Il fonctionne dans de nombreux cas, n'échoue pas lorsque des valeurs comme {} sont transmises et est très concis. De plus, il retourne false comme valeur par défaut plutôt que non défini ou lançant une erreur, ce qui est plus utile dans le développement Javascript de type lâche. Bravo aux autres réponses qui l'ont suggéré!

BishopZ
Pour revenir à vos objectifs, le seul problème avec votre troisième et meilleure solution est qu'elle ne répond pas à l'objectif n ° 1 - elle ne retournera vrai que pour une valeur de 'true', mais pas pour une entrée véridique. Afin de le rendre conforme à l'objectif n ° 1, il n'est que légèrement plus concis que la solution n ° 2 et beaucoup moins lisible.
JMTyler
return /^(true|yes|1|t|y)$/i.test(str);
Kevin Boucher
7

Je suis un peu en retard, mais j'ai un petit extrait pour ce faire, il maintient essentiellement tous JScripts truthey / Falsey / sale ness mais comprend "false"comme une valeur acceptible pour faux.

Je préfère cette méthode à celles mentionnées car elle ne repose pas sur un tiers pour analyser le code (ie: eval / JSON.parse), ce qui est exagéré dans mon esprit, il est assez court pour ne pas nécessiter de fonction utilitaire et maintient autres conventions 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
la source
7

une autre solution. 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
};

cas de test exécutés dans le nœud

> 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
la source
7

Dieu sacré, certaines de ces réponses sont tout simplement sauvages. J'adore JS et son nombre infini de façons d'écorcher un bool.

Ma préférence, que j'ai été choquée de ne pas voir déjà, est:

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

Bon mot

Nous avons juste besoin de prendre en compte la "fausse" chaîne puisque toute autre chaîne (y compris "vraie") l'est déjà true.

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

Tester

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

Une version plus exaustive

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

Tester

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
la source