Pytanie Jak mogę przekonwertować ciąg na boolean w JavaScript?


Czy mogę przekonwertować ciąg znaków reprezentujący wartość boolowską (np. "Prawda", "fałsz") na typ nieodłączny w kodzie JavaScript?

Mam ukryty formularz w HTML, który jest aktualizowany w oparciu o wybór użytkownika na liście. Ten formularz zawiera pola, które reprezentują wartości logiczne i są dynamicznie wypełniane przez wewnętrzną wartość boolowską. Jednak po umieszczeniu tej wartości w ukrytym polu wejściowym staje się ciągiem znaków.

Jedyny sposób, jaki mogłem znaleźć w celu określenia wartości boolowskiej pola, po przekonwertowaniu na ciąg, był zależny od literalnej wartości jego reprezentacji łańcuchowej.

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

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


1840
2017-11-05 00:13


pochodzenie


Po prostu podkreślam dziwny przykład unikania porównywania potrójnych równań: Mam funkcję currentSortDirection() to się zwraca 1 dla sortowania wstępującego, 0 dla rodzaju zstępującego, i -1 dla nie ustawionego. Za pomocą while (currentSortDirection() != desiredSortDirection) { sortColumn() } działa świetnie, ponieważ -1 != true  i  -1 != false... ale zmieniając to na while (Boolean(currentSortDirection) !== ...) {...} siły -1 do a true, wymagając dodatkowej pary linii prep, po prostu aby jshint był szczęśliwy. - Droogans
"Czy istnieje lepszy sposób, aby to osiągnąć?" - jest na pewno gorszy sposób: D string=(string==String(string?true:false))?(string?true:false):(!string?true:fa‌​lse); - Mark K Cowan
Łatwe obsługiwanie smyczków i boolów: function parseBool(val) { return val === true || val === "true" } - WickyNilliams
@Znak function checkBool(x) { if(x) {return true;} else {return false;} } - Sebi
@Sebi: Zapomniałeś to udokumentować: if (checkBool(x) != false) { ... } else { ... } - Mark K Cowan


Odpowiedzi:


Zrobić:

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

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

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

Nie:

Powinieneś prawdopodobnie bądź ostrożny przy użyciu tych dwóch metod dla twoich szczególnych potrzeb:

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

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

Każdy łańcuch, który nie jest pustym łańcuchem, zostanie oceniony na true używając ich. Chociaż są to najczystsze metody, jakie mogę wymyślić, dotyczące konwersji boolowskiej, myślę, że nie są one tym, czego szukasz.


2473



myValue === 'true'; jest dokładnie równoważny myValue == 'true';. Nie ma żadnej korzyści z używania === koniec == tutaj. - Tim Down
podążam Rada Crockforda I użyć === i !== kiedykolwiek ma to sens, co prawie zawsze. - guinaps
Co na przykład z "PRAWDZIWĄ" we wszystkich wielkich literach? - BMiner
@guinaps Zwykle podążam za radą Crockforda, ale == vs. === scenariusz jest jednym z niewielu, w których nie. ja całkowicie nie zgadzam się, że "prawie zawsze" ma sens w użyciu ===. Luźno napisane języki istnieć ponieważ nie chcemy dbać o typ; jeśli sprawdzimy coś podobnego if (price >= 50) nie obchodzi nas, czy zaczęło się od sznurka. Mówię, większość czasu, my chcieć typy do żonglowania. W rzadkich przypadkach, gdy nie chcemy żonglowania typem (np. if (price === null)), a następnie używamy ===. To jest to, co robiłem od lat i mam nigdy miał problem. - JMTyler
@JMTyler może być niewidoczny dla programisty konserwacji. Zawsze korzystaj z właściwego operatora porównania! Jeśli wiesz "na pewno" typy po obu stronach, ale nie używaj ===, nie będę miał tej wiedzy, kiedy patrzę na twój kod później. Jeśli Twój kod zostanie ponownie użyty, może stać się koszmarem. Jeśli NAPRAWDĘ chcesz, aby twoje typy były "żonglowane", tak jak mówisz, używaj "==", ale zbyt wielu programistów JS wykaże to zbyt łatwo, lepiej dokręcić swój kod. Jak często chcę, aby ciąg "false" oznaczał boolean "true"? - aikeru


Ostrzeżenie

Ta wysoko poparta starsza odpowiedź jest poprawna pod względem technicznym, ale obejmuje tylko bardzo specyficzny scenariusz, gdy wartość ciągu jest DOKŁADNIE "true" lub "false" (MUSZĄ być również małe litery).

Niepoprawny ciąg jsonów przeszedł do poniższych funkcji WYZNACZYĆ wyjątek.


Oryginalna odpowiedź:

Co powiesz na?

JSON.parse("true");

lub z jQuery

$.parseJSON("true");

518



Problem polega na tym, że wiele potencjalnych wartości generuje błąd analizy, który zatrzymuje wykonywanie JS. Więc uruchamianie JSON.parse ("FALSE") bombarduje JavaScript. Chodzi mi o to, że nie chodzi o proste rozwiązywanie tych konkretnych przypadków, ale także o odporność na inne przypadki. - BishopZ
Łatwo powiedzieć po prostu JSON.parse("TRUE".toLowerCase()) aby mógł poprawnie parsować. - Yuck
@Ebenezar dlaczego zależy nam na ie7? Ma około 1% udziału w światowym rynku. - Todd
@Ebenezar Mogę to uszanować, ale mój czas poświęca się optymalizacji na inne> 99%. Ludzie używający ie7 na 15 oczywiście nie są zbytnio zainteresowani internetem. Twoje zdrowie. - Todd
dlaczego jest tak dużo przebojów? To nieefektywne i straszne. Co dalej? 'true'.length === 4? - Maksim Vi.


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

186



W rzeczywistości można go uprościć. 1) Nie ma potrzeby testowania "true", "yes" i "1". 2) toLowerCase nie wraca 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
@Robert, niezły, ale wolałbym mieć domyślną wartość false zamiast. - drigoangelo
@drigoangelo Posiadanie default: return true; jest z pewnością możliwe. Ale to zmieniłoby zachowanie funkcji. - Robert
Myślałem, że to najlepsza odpowiedź i chciałem ją tutaj rozwinąć: stackoverflow.com/questions/263965/... - BrDaHa
jeśli normalizujesz dane, wywołując funkcję .toLowerCase (), możesz chcieć rzucić przycinanie (), aby również usunąć białe spacje - jCuga


Myślę, że jest to 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

120



Kiedy możesz odbierać ciąg wielkimi literami lub boolowskimi, wtedy String(a).toLowerCase() === 'true' - pauloya
@PauloManuelSantos ten jest naprawdę najlepszy jeden-liniowy tutaj :) świetnie! - Adam Lukaszczyk
String("what about input like this that isn't a bool?") == "true" - Thomas Eding
@ThomasEding false ... co chcesz, aby powrócił? - Snowburnt
może nawet skrócić, nie używając String() konstruktor: true+'' === 'true' // true - Todd


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 (zobacz komentarze), które chcieliby rozszerzyć obiekt String, aby to uzyskać, ale martwią się o możliwość wyliczania i martwią się o konflikt 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 będzie działać w starszych przeglądarkach, a Firefox pokazuje fałsz, podczas gdy Opera, Chrome, Safari i IE pokazują prawdę. Bug 720760)


105



Niezbyt dobry pomysł na modyfikację prototypu wbudowanych obiektów! - DTrejo
Zawsze możesz poprzedzić tę funkcję, jeśli obawiasz się, że zakłóci to jakiś inny kod. Jeśli jakiś kod nadal się psuje, ten kod jest po prostu zbyt kruchy i powinien zostać naprawiony. Jeśli twoja dodana funkcja sprawia, że ​​obiekt jest zbyt ciężki, gdy powoduje problem z wydajnością dla innego kodu, to oczywiście nie chcesz tego robić. Ale nie wydaje mi się, że generalnie należy rozszerzać wbudowane obiekty. Nie byłoby to również możliwe do przedłużenia, gdyby tak było. - Shadow2531
Nie należy modyfikować prototypu - Szymon Wygnański
@DTrejo @Szymon Nie zgadzam się. Jest to dokładnie ten rodzaj rzeczy, dla których jest przeciążenie prototypu. Jeśli boisz się złamania (słabego) kodu, który polega na .. w, istnieją sposoby, aby ukryć właściwości przed wyliczeniem. Widzieć Object.defineProperty. - devios1
Boolean parsowanie nie należy do klasy String. W rezultacie otrzymasz dowolną liczbę analizatorów i konwersję śmieci. -1 ogólnie do zmieniających się prototypów. -1 do rozwiązań, które nie działają w różnych przeglądarkach. -1 dla złego projektu. - Thomas W


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 pole wyboru jest zaznaczone:

var isTrueSet = document.myForm.IS_TRUE.checked;

Zakładając, że jeśli jest zaznaczone, to "set" jest równe true. To jest prawdziwe / fałszywe.


103



dlaczego miałbyś robić trójskładnik? już masz tam boolean - nickf
Ponieważ możesz? Co masz na myśli mówiąc "już masz tam boolean"? - Jared Farrish
Jared, === już jest warunkiem boolowskim, trójskładnik jest zbędny. - FlySwat
Prawdziwe. W każdym razie nienawidzę trójki. Cóż, myślę, że mam rację w sprawie toLowerCase, więc zredagowałem to, by usunąć trójząb. - Jared Farrish
Spowoduje to zgłoszenie wyjątku, jeśli myValue Zdarza się null, true lub jakiś inny typ ... - mik01aj


Wood-eye uważaj. Po zapoznaniu się z konsekwencjami po zastosowaniu górnej odpowiedzi z ponad 500 wyższymi wersjami, czuję się zobowiązany do opublikowania czegoś, co jest rzeczywiście przydatne:

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

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

I zakończyć 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]));}

39



Pamiętaj tylko, że starsze przeglądarki mogą potrzebować polyfill JSON, jeśli użyjesz pierwszej metody. - DRaehal
Jak szybko przesyłać "fałszywe" ciągi do false wartość boolowska z JSON.parse? Pod względem procesora, wydajności pamięci - Green