Jak przekonwertować ciąg znaków na wartość logiczną w JavaScript?


2549

Czy mogę przekonwertować ciąg reprezentujący wartość logiczną (np. „Prawda”, „fałsz”) na typ wewnętrzny w JavaScript?

Mam ukryty formularz w HTML, który jest aktualizowany na podstawie wyboru użytkownika na liście. Ta forma zawiera niektóre pola, które reprezentują wartości logiczne i są dynamicznie wypełniane wewnętrzną wartością logiczną. Jednak po umieszczeniu tej wartości w ukrytym polu wejściowym staje się ciągiem.

Jedynym sposobem, w jaki mogłem znaleźć wartość logiczną pola, po przekształceniu w ciąg, było poleganie na dosłownej wartości jego reprezentacji.

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

Czy istnieje lepszy sposób na osiągnięcie tego?


50
„Czy istnieje lepszy sposób na osiągnięcie tego?” - z pewnością jest gorszy sposób: Dstring=(string==String(string?true:false))?(string?true:false):(!string?true:fa‌​lse);
Mark K Cowan

3
Łatwo obsługiwać ciągi znaków i function parseBool(val) { return val === true || val === "true" }
bools

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

2
@Sebi: Zapomniałeś go udokumentować:if (checkBool(x) != false) { ... } else { ... }
Mark K Cowan

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

Odpowiedzi:


3474

Zrobić:

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

Można to zaostrzyć za pomocą operatora tożsamości ( ===), który nie dokonuje żadnych domyślnych konwersji typu, gdy porównywane zmienne mają różne typy, zamiast operatora równości ( ==).

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

Nie:

Prawdopodobnie powinieneś zachować ostrożność przy stosowaniu tych dwóch metod do swoich konkretnych potrzeb:

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

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

Każdy ciąg, który nie jest pustym ciągiem, oceni je trueprzy użyciu. Chociaż są to najczystsze metody, jakie mogę wymyślić w odniesieniu do konwersji boolowskiej, myślę, że nie są tym, czego szukasz.


196
myValue === 'true';jest dokładnie równoważny z myValue == 'true';. Nie ma żadnych korzyści w użyciu ===ponad ==tutaj.
Tim Down

551
Postępuję zgodnie z radami i zaleceniami Crockforda=== i !==zawsze, gdy ma to sens, co prawie zawsze.
guinaps,

55
A na przykład „PRAWDA” wielkimi literami?
BMiner,

102
@ guinaps Zwykle podążam za radą Crockforda, ale scenariusz ==kontra ===jest jednym z niewielu, w którym nie. I całkowicie zgadzam się, że to „prawie zawsze” sens stosowania ===. Istnieją luźno napisane języki , ponieważ nie chcemy przejmować się typem; jeśli sprawdzimy coś takiego if (price >= 50), nie obchodzi nas, czy zaczyna się od łańcucha. Mówię, że przez większość czasu chcemy żonglować typami. W rzadkich przypadkach, gdy nie chcemy żonglowania typami (np. if (price === null)), Używamy ===. Tak robiłem od lat i nigdy nie miałem problemu.
JMTyler

169
@JMTyler może przeoczyć programistę konserwacji. Zawsze używaj właściwego operatora porównania! Jeśli znasz „na pewno” typy po obu stronach, ale nie używasz ===, nie będę miał tej wiedzy, kiedy popatrzę na twój kod później. Ponowne użycie kodu może stać się koszmarem. Jeśli NAPRAWDĘ chcesz, aby twoje typy były „żonglowane”, jak mówisz, użyj „==”, ale zbyt wielu deweloperów JS zbyt łatwo potknie się o to, lepiej zaostrzyć kod. Jak często chcę, aby ciąg „fałsz” oznaczał wartość logiczną „prawda”?
aikeru

687

Ostrzeżenie

Ta wysoce pozytywna, starsza odpowiedź jest technicznie poprawna, ale obejmuje tylko bardzo konkretny scenariusz, gdy wartość ciągu to DOKŁADNIE "true"lub "false".

Niepoprawny ciąg json przekazany do tych funkcji poniżej ZWRÓCI wyjątek .


Oryginalna odpowiedź:

Co powiesz na?

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

lub z jQuery

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

62
Problem polega na tym, że wiele potencjalnych wartości generuje błąd analizy, który zatrzymuje wykonywanie JS. Więc uruchomienie JSON.parse („FALSE”) bombarduje Javascript. Myślę, że sedno tego pytania nie polega po prostu na rozwiązywaniu tych konkretnych przypadków, ale także na odporności na inne sprawy.
BishopZ

3
@Luke to rozwiązanie jest dokładnie tym, czego potrzebowałem; cóż, owijając go w próbę ... choć złapać. Chciałem przekonwertować na bool tylko wtedy, gdy była to wartość boolowska w ciągu; w przeciwnym razie po prostu użyj dostarczonego ciągu. To działa! Dzięki.
jedmao

47
Po prostu powiedz JSON.parse("TRUE".toLowerCase()), że można poprawnie parsować.
Fuj

27
dlaczego jest tyle głosów poparcia? To jest nieefektywne i okropne. Co dalej? '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// dla pewności
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
W rzeczywistości można to uprościć. 1) Nie ma potrzeby, aby przetestować "true", "yes"a "1". 2) toLowerCasenie zwraca null. 3) Boolean(string)jest taki sam jak string!==""tutaj. =>switch(string.toLowerCase()) {case "false": case "no": case "0": case "": return false; default: return true;}
Robert

15
@Robert, fajny, ale wolałbym zamiast tego mieć wartość domyślną false.
drigoangelo

@drigoangelo Posiadanie default: return true;jest z pewnością możliwe. Ale zmieniłoby to zachowanie funkcji.
Robert

2
Pomyślałem, że to najlepsza odpowiedź i chciałem się tutaj rozwinąć: stackoverflow.com/questions/263965/…
BrDaHa

9
jeśli normalizujesz dane, wywołując funkcję .toLowerCase (), możesz chcieć wprowadzić trim (), aby usunąć również białe spacje
jCuga

174

Myślę, że to jest bardzo uniwersalne:

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

To idzie:

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

20
Kiedy możesz otrzymać ciąg String(a).toLowerCase() === 'true'
pisany

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

6
@ThomasEding false ... co chcesz, aby powrócił?
Snowburnt

2
może nawet skrócić, nie używając String()konstruktora:true+'' === 'true' // true
Todd

1
BTW, dla 1 lub 0 powinien również rzucić na false lub true
Miguel

128

Pamiętaj, aby dopasować wielkość liter:

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

Ponadto, jeśli jest to pole wyboru elementu formularza, możesz również wykryć, czy to pole wyboru jest zaznaczone:

var isTrueSet = document.myForm.IS_TRUE.checked;

Zakładając, że jeśli jest zaznaczone, to jest „ustawione” równe true. To ocenia się jako prawda / fałsz.


3
Spowoduje to wyjątek, jeśli myValuetak się stanie null, truelub jakiś inny typ ...
mik01aj

116

Możesz użyć wyrażeń regularnych:

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

Jeśli chcesz rozszerzyć klasę String, możesz:

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

alert("true".bool());

Dla tych (patrz komentarze), którzy chcieliby rozszerzyć obiekt String, aby uzyskać to, ale martwią się o możliwość wyliczenia i martwią się kolizją z innym kodem, który rozszerza obiekt String:

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

(Oczywiście nie działa w starszych przeglądarkach, a Firefox pokazuje false, podczas gdy Opera, Chrome, Safari i IE pokazują true. Bug 720760 )


10
Zawsze możesz poprzedzić funkcję, jeśli boisz się, że będzie ona zakłócać działanie innego kodu. Jeśli jakiś kod nadal się psuje, kod ten jest po prostu zbyt kruchy i powinien zostać naprawiony. Jeśli dodana funkcja powoduje, że obiekt jest zbyt ciężki, gdy powoduje problem z wydajnością dla innego kodu, to oczywiście nie chcesz tego robić. Ale nie sądzę, aby rozszerzanie wbudowanych obiektów było złym pomysłem. W takim przypadku nie byłyby również publicznie rozszerzalne.
Shadow2531,

41
@DTrejo @Szymon Nie zgadzam się. Jest to dokładnie rodzaj przeciążenia, do jakiego służy prototyp. Jeśli boisz się, że to zepsuje (słaby) kod, który polega na for..in, istnieją sposoby na ukrycie właściwości przed wyliczeniem. Zobaczyć Object.defineProperty.
devios1

parseBool
Naśladując

8
Parsowanie boolowskie nie należy do klasy String .. skończyłbyś z dowolną ilością parserów śmieci i konwersji tam. -1 do ogólnej zmiany prototypów. -1 do rozwiązań, które nie działają w różnych przeglądarkach. -1 dla złego projektu.
Thomas W

1
Oto porównanie wszystkich odpowiedzi. stackoverflow.com/a/28588344/2824333
sospedra

50

Drewno-oko uważaj. Po zapoznaniu się z konsekwencjami po zastosowaniu najwyższej odpowiedzi z ponad 500 głosami pozytywnymi czuję się zobowiązany do opublikowania czegoś, co jest naprawdę przydatne:

Zacznijmy od najkrótszego, ale bardzo ścisłego sposobu:

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

I zakończ w odpowiedni, bardziej tolerancyjny sposób:

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

Testowanie:

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

Pamiętaj tylko, że starsze przeglądarki mogą wymagać wypełnienia JSON, jeśli zastosujesz pierwszą metodę.
DRaehal

1
Jak szybko można rzutować „fałszywy” ciąg znaków na falsewartość boolowską JSON.parse? Pod względem wydajności procesora i pamięci
Green

Czy nie byłoby łatwiej po prostu zacząć od (str) {...} wyeliminowania czegoś, co już jest fałszywe? I w tym warunku, po prostu trzeba się martwić o zwrócenie wartości true, ponieważ już kończy się zwrotem false!
Larphoid

Pamiętaj, że możesz skrócić wiele testów ciągów za pomocą ([„true”, „yes”, „1”]. IndexOf (str.toLowerCase (). Trim ())! = -1) i użyj rezerwy Boolean (str) obejmujący rzeczy takie jak „null”
Scott,

38

Pomyślałem, że odpowiedź @Steven była najlepsza i zająłem się znacznie większą liczbą przypadków, niż gdyby przychodząca wartość była tylko łańcuchem. Chciałem go trochę rozszerzyć i zaoferować:

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

Nie falsemusisz uwzględniać wszystkich spraw, jeśli znasz już wszystkie truesprawy, które musisz uwzględnić. Możesz przekazać do tej metody wszystko, co może przekazać truewartość (lub dodać inne, to całkiem proste), a wszystko inne będzie brane pod uwagęfalse


Używam tego, ponieważ obejmuje rzeczy, które otrzymujesz z atrybutów ElementNodes XML / HTML, takie jakautocomplete="on"
philk

2
Dodałbym .trim () przed toLowerCase ()
Luis Lobo Borobia

34

Uniwersalne rozwiązanie z parsowaniem 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

AKTUALIZACJA (bez JSON):

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

Stworzyłem również skrzypce, aby to przetestować http://jsfiddle.net/remunda/2GRhG/


1
Wersja „bez JSON” ma pewną wadę: val = "0"; console.log (!! (+ val || String (val) .toLowerCase (). replace (!! 0, ''))); produkuje prawda
Etienne

3
getBool(undefined)zawiesza się Podczas korzystania z oryginalnej wersji JSON i zwraca wartość true dla 2. wersji. Oto trzecia wersja, która zwraca false: function getBool (val) {var num; return val! = null && (! isNaN (num = + val)? !! num: !! String (val) .toLowerCase (). replace (!! 0, '')); }
Ron Martinez,

31

Twoje rozwiązanie jest w porządku.

Użycie ===byłoby po prostu głupie w tym przypadku, ponieważ pole valuezawsze będzie oznaczało String.


17
Dlaczego uważasz, że byłoby głupie w użyciu ===? Pod względem wydajności byłoby dokładnie tak samo, gdyby oba typy były łańcuchami. W każdym razie wolę używać, ===ponieważ zawsze unikam używania ==i !=. Uzasadnienie: stackoverflow.com/questions/359494/…
Mariano Desanze

3
Ponieważ valuezawsze będzie stringani ==nor, ani ===głupie. Oba są właściwym narzędziem do tego zadania. Różnią się tylko, gdy typy nie są równe. W takim przypadku ===po prostu powraca falsepodczas ==wykonywania skomplikowanego algorytmu przymusu przed porównaniem.
Robert

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

Spowoduje to powrót falsedo każdej wartości falsy i truedla każdej wartości truthy wyjątkiem 'false', 'f', 'no', 'n'oraz '0'(bez uwzględniania wielkości liter).

// 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

Obiekt boolowski nie ma metody „parsowania”. Boolean('false')zwraca true, więc to nie zadziała. !!'false'również zwraca true, więc to też nie zadziała.

Jeśli chcesz, aby ciąg 'true'zwracał wartość logiczną, truea ciąg 'false'zwracał wartość logiczną false, najprostszym rozwiązaniem jest użycie eval(). eval('true')zwraca true i eval('false')zwraca false. Pamiętaj jednak o wpływie na wydajność podczas korzystania eval().


Aby zrozumieć, co jest „nie tak” (lub dobrze) z eval - sprawdź artykuły, takie jak javascriptweblog.wordpress.com/2010/04/19/how-evil-is-eval lub wyszukaj na
stosie przepływ

2
Zgadzam się, że var isTrueSet = (myValue === 'true');to najlepsza odpowiedź.
thdoan

Podoba mi się, że jest zwięzłe. Ale zawodzi spektakularnie w podstawowym przypadku eval('TRUE'); udowadniając raz jeszcze, że eval()jest zły.
Bałwan

@Area 51 Detective Fiction, w ten sam sposób, JSON.parse('TRUE')z poniższej odpowiedzi również zawodzi spektakularnie. Bardzo łatwo jest wymusić warunek błędu w JavaScript (lub w dowolnym innym języku). Aby to wyjaśnić, najpierw należy znormalizować ciąg, np.var myValue = document.myForm.IS_TRUE.value.toLowerCase(); var isTrueSet = (myValue==='true' || myValue==='false') ? eval(myValue) : false;
thdoan

1
@ 10basetom: Całkiem poprawnie. Powinieneś uwzględnić .toLowerCase()w odpowiedzi, o co mi chodzi. Nie próbuję niczego zmuszać. Wielkie litery TRUEsą na tyle powszechną wartością, że zwraca je wiele widżetów interfejsu użytkownika.
Bałwan

17

Zostało to zaczerpnięte z przyjętej odpowiedzi, ale tak naprawdę ma bardzo słaby punkt i jestem zszokowany, skąd wzięła się ta liczba głosów pozytywnych, problem z tym, że musisz wziąć pod uwagę wielkość ciągu znaków, ponieważ rozróżnia się wielkość liter

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

16

Używam następujących:

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

Ta funkcja wykonuje zwykły logiczny przymus, z wyjątkiem ciągów „false” (bez rozróżniania wielkości liter) i „0”.


16

Istnieje wiele odpowiedzi i trudno jest wybrać jedną. W moim przypadku wybieram priorytet wydajności, więc tworzę ten plik jsPerf, który, mam nadzieję, może tu rzucić nieco światła.

Podsumowanie wyników (im wyższy, tym lepszy):

  1. Oświadczenie warunkowe : 2 826 922
  2. Włącz skrzynkę na obiekcie Bool : 2 825 469
  3. Przesyłanie do JSON : 1 867 774
  4. !! konwersje : 805,322
  5. Prototyp sznurka: 713,637

Są one powiązane z odpowiednią odpowiedzią, w której można znaleźć więcej informacji (za i przeciw) na temat każdego z nich; szczególnie w komentarzach.


„coś poszło nie tak” podczas próby wyświetlenia testu
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
Możesz użyć true.toString () zamiast „true”, aby być jeszcze bardziej czystym :-)
tillda

Nie zmieniaj globalizacji, staraj się trzymać swoje zmiany w izolacji, może function parseBooleanzamiast tego utwórz nową
Steel Brain

13

Po prostu szukasz wyrażenia

/^true$/i.test(myValue)

jak w

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

Testuje myValueto na wyrażenie regularne, bez rozróżniania wielkości liter i nie modyfikuje prototypu.

Przykłady:

/^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

Aby przekonwertować zarówno ciąg znaków („prawda”, „fałsz”), jak i wartość logiczną na wartość logiczną

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

Gdzie flagmoże być

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

12

Dostępnych jest już tak wiele odpowiedzi. Ale w niektórych sytuacjach przydatne mogą być następujące czynności.

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

Może to być przydatne, gdy jeden z przykładów nie zawiera wartości boolowskich.

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

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

10

dlaczego nie spróbujesz czegoś takiego

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

Zwróci błąd, gdy podany zostanie jakiś inny tekst, a nie prawda lub fałsz, bez względu na wielkość liter, a także przechwyci liczby jako

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

10

Ta funkcja może obsługiwać zarówno ciąg znaków, jak i logiczną wartość true / false.

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

Pokaz poniżej:

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

Używam tego

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"

Jest to dobre, ale działa tylko z typem String. Wyobraź sobie, że potrzebuje tego zmienna, która może "true"lub true. Jeśli przyjdzie drugi, to nie zadziała. Czy możliwe jest document.prototypeużycie tego, gdziekolwiek chcemy?
MarceloBarbosa

To wygląda elegancko. Dobra robota! Zauważyłem jednak, że przeciążenie podstawowych prototypów w dużych aplikacjach JS (które również wymagają testów jednostkowych) może spowodować pewne nieoczekiwane zachowanie (a mianowicie, gdy chcesz iterować z „for” przez tablicę, która ma przeciążony prototyp, otrzymasz niektóre właściwości, których normalnie byś się nie spodziewał). Zostałeś ostrzeżony. ;)
cassi.lup

twój wariant, który akceptuje również funkcję logiczną StringOrElse2Bool (szl) {if (typeof szl === "string") {return ["no", "false", "0", "off"]. indexOf (sob.toLowerCase ())! == -1? fałsz PRAWDA; } else {return !!
szl

8

Najprostszym sposobem (zakładając, że ciąg będzie „prawda” lub „fałsz”), jest:

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

Zawsze używaj operatora === zamiast operatora == dla tego typu konwersji!


4
O jakiej konwersji mówiłeś? :-)
YMMD

1
Porównując ciąg w javascript, nie ma różnicy między używaniem operatorów == lub ===, gdy nie używa się konwersji. Tutaj porównujesz do ciągów, dlatego nie ma konwersji typu. Zobacz stackoverflow.com/questions/359494/…
ars265

8

Jak powiedział @ Shadow2531, nie można po prostu przekonwertować go bezpośrednio. Sugerowałbym również, abyś wziął pod uwagę ciąg znaków oprócz „prawda” i „fałsz”, które są „prawda” i „falsey”, jeśli twój kod będzie ponownie używany / używany przez innych. Oto, czego używam:

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

Musisz oddzielić (w swoim myśleniu) wartość swoich wyborów i reprezentację tej wartości.

Wybierz punkt w logice JavaScript, w którym muszą przejść z wartowników łańcuchowych na typ rodzimy i dokonać porównania tam, najlepiej tam, gdzie robi się to tylko raz dla każdej wartości, którą należy przekonwertować. Pamiętaj, aby zająć się tym, co musi się zdarzyć, jeśli wartownik nie jest tym, który zna skrypt (tj. Czy domyślnie przyjmujesz wartość true czy false?)

Innymi słowy, tak, musisz polegać na wartości łańcucha. :-)


7

Uważam, że ma ono na celu spełnienie trzech celów:

  • Zwraca true / false dla wartości true i falsey, ale także zwraca true / false dla wielu wartości stringów, które byłyby true lub falsey, gdyby były booleanami zamiast stringów.
  • Po drugie, zapewnij elastyczny interfejs, aby wartości inne niż określone nie zawiodły, a raczej zwróciły wartość domyślną
  • Po trzecie, zrób to wszystko z możliwie najmniejszym kodem.

Problem z używaniem JSON polega na tym, że nie działa, powodując błąd JavaScript. To rozwiązanie nie jest elastyczne (choć spełnia wymagania 1 i 3):

JSON.parse("FALSE") // fails

To rozwiązanie nie jest wystarczająco zwięzłe:

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

Pracuję nad rozwiązaniem tego dokładnego problemu w przypadku pliku Typecast.js . A najlepszym rozwiązaniem dla wszystkich trzech celów jest ten:

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

Działa w wielu przypadkach, nie zawodzi, gdy przekazywane są wartości takie jak {} i jest bardzo zwięzły. Zwraca także wartość false jako wartość domyślną, a nie niezdefiniowaną lub zgłaszającą błąd, co jest bardziej przydatne w luźno napisanym języku JavaScript. Brawo dla innych odpowiedzi, które to sugerowały!


Wracając do swoich celów, jedynym problemem z trzecim i najlepszym rozwiązaniem jest to, że nie spełnia on Celu 1 - zwróci wartość true tylko dla wartości 'true', ale nie dla żadnego prawdziwego wkładu. Aby osiągnąć cel nr 1, jest tylko nieco bardziej zwięzły niż rozwiązanie nr 2 i znacznie mniej czytelny.
JMTyler

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

7

Jestem trochę późno, ale mam mały fragment, aby to zrobić, to zasadniczo zachowuje wszystkie JScripts truthey / falsey / brudny -ness ale zawiera "false"jako acceptible wartości dla fałszu.

Wolę tę metodę od tych wymienionych, ponieważ nie polega ona na analizie kodu przez inną firmę (np .: eval / JSON.parse), co jest moim zdaniem przesadą, jest wystarczająco krótkie, aby nie wymagać funkcji narzędzia i utrzymuje inne konwencje 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

inne rozwiązanie. 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
};

przypadki testowe działają w węźle

> 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

Boże, niektóre z tych odpowiedzi są po prostu dzikie. Uwielbiam JS i jego nieskończoną liczbę sposobów na skórkę bool.

Moje preferencje, których nie byłem zaskoczony, to:

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

6

Jedna wkładka

Musimy tylko uwzględnić „fałszywy” ciąg, ponieważ jakikolwiek inny ciąg (w tym „prawda”) już istnieje true.

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

Test

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

Bardziej wyczerpująca wersja

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.