Nie można ustawić wartości logicznych w LocalStorage?


112

Zauważyłem, że nie mogę ustawić wartości logicznych w localStorage?

localStorage.setItem("item1", true);
alert(localStorage.getItem("item1") + " | " + (localStorage.getItem("item1") == true));

Zawsze wyświetla alerty, true | falsegdy próbuję to sprawdzić localStorage.getItem("item1") == "true", alerty są prawdziwe ... Jak ustawić element localStoragejako prawdziwy?

Nawet jeśli jest to ciąg, myślałem, ===że sprawdzę tylko typ?

Więc

alert("true" == true); // should be true? 

Odpowiedzi:


69

Implementacja Storage w Firefoksie może przechowywać tylko ciągi znaków, ale we wrześniu 2009 roku W3C zmodyfikowało wersję roboczą, aby zaakceptować dowolne dane.Wdrażanie (nadal) nie zostało jeszcze zakończone( patrz Edycja poniżej ).

Więc w twoim przypadku wartość logiczna jest konwertowana na łańcuch.

Co do tego "true" != true, jak napisano w opisie Equal ( ==) w MDC *:

Jeśli dwa operandy nie są tego samego typu, JavaScript konwertuje operandy, a następnie stosuje ścisłe porównanie. Jeśli którykolwiek z operandów jest liczbą lub wartością logiczną, operandy są konwertowane na liczby, jeśli to możliwe; w przeciwnym razie, jeśli jeden z operandów jest łańcuchem, drugi operand jest konwertowany na łańcuch, jeśli to możliwe.

Zauważ, że ciąg jest konwertowany na liczbę zamiast na wartość logiczną . Ponieważ "true"przekonwertowana na liczbę jest NaN, nie będzie równa, więc falsejest zwracana.

(*: Aby zapoznać się z aktualnym standardem, patrz ECMA-262 §11.9.3 „Algorytm abstrakcyjnego porównania równości”)


Edit:setItem interfejs został przywrócony do zaakceptowania ciągi tylko na 2011 Sept 1st projektu , aby dopasować zachowanie istniejących wdrożeń, jak żaden z producentów są zainteresowane wspieraniem przechowywanie nie-strun. Szczegółowe informacje można znaleźć pod adresem https://www.w3.org/Bugs/Public/show_bug.cgi?id=12111 .


2
Jeśli któryś z operandów jest liczbą lub wartością logiczną, operandy są konwertowane na liczby, jeśli to możliwe - zupełnie nie zdawałem sobie z tego sprawy. Pomyślałem, że jeśli jeden byłby struną, drugi został rzucony na strunę. Pozdrawiam (+1).
Andy E,

2
@Andy, sprawdź te przydatne uwagi na ten temat.
CMS,

91

W tej chwili wszystkie implementacje Safari , WebKit, Chrome, Firefox i IE są zgodne ze starą wersją standardu WebStorage, w którym wartość elementów pamięci może być tylko ciągiem znaków.

Opcją byłoby użycie JSON parsei stringifymetody do serializacji i deserializacji danych, jak zasugerowałem jakiś czas temu w innym pytaniu , na przykład:

var value = "true";
JSON.parse(value) === true; // true

4
To oczywiście ulegnie awarii, jeśli przekazany ciąg valuenie jest prawidłowym JSON.parse("a random string")
plikiem

3
True @AdonisK. Ale jeśli używa JSON.stringify podczas ustawiania wszystkich wartości, jest w stanie zwolnić z odpowiedzialności za wysyłanie prawidłowego kodu JSON do biblioteki. A to jest bardzo stabilna biblioteka.
Colt McCormack,

11

Moje rozwiązania:

function tytPreGetBool(pre) {
    return localStorage.getItem(pre) === 'true';
}

2
@koppor Może dlatego, że jeśli getItem kiedykolwiek zwróci wartość logiczną, to ta metoda da fałszywe wyniki, ponieważ true == 'true'jest false.
jox

8
... lub zwykły localStorage.getItem(pre)==='true'bez reszty
phil294,

1
@koppor, dlaczego ten głos został odrzucony? ponieważ samozwańcze układacze są przepełnione, dosłownie :)
Ayyash,

1
„? true: false” jest niepotrzebne, ponieważ localStorage.getItem (pre) == 'true' już daje wynik boolowski
FelipeDrumond

6

Jest to związane z odpowiedzią CMS.

Oto mała funkcja, której używałem do obsługi części parsującej tego problemu (funkcja będzie nadal działać właściwie po tym, jak implementacje przeglądarki dogonią specyfikację, więc nie musisz pamiętać o późniejszej zmianie kodu):

function parse(type) {
   return typeof type == 'string' ? JSON.parse(type) : type;
}

1
Czy nie jest to niepotrzebne w porównaniu z JSON.parse? JSON.parse ("true") i JSON.parse (true) już zwracają wartość true, więc nadal będą działać poprawnie po zaimplementowaniu przez przeglądarki wartości boolean localstorage
bscan

3

Użyj store.js :

localStorage.setItem('isUser', true)
localStorage.getItem('isUser') === "true" //true
npm i -D store

store.get('isUser')  //true

4
Ale czy naprawdę konieczne jest uwzględnienie całej biblioteki tylko dla tego prostego zadania konwersji ciągu znaków na wartość logiczną?
jayqui

1

Nie jestem pewien, czy LocalStorage może zapisywać wartości logiczne, ale mogę powiedzieć, że kiedy to zrobisz alert("true" == true);, nigdy nie zostanie to ocenione jako prawda, ponieważ niejawnie porównujesz ciąg z wartością logiczną. Dlatego warto ustawić wartości logiczne, których używasz truezamiast "true".


1
A co z alertem („1” == 1)? Javascript to dziwna (i niespójna) bestia.
wydający

@spender: to dlatego, że odpowiedni operand jest rzutowany na łańcuch w celu porównania. "1" === 1faktycznie zwróci fałsz.
Andy E,

@Kenny: whoops facepalm , dzięki za korektę :-) Byłem zdezorientowany z powodu tego, jak booleany rzucają na struny.
Andy E,

1

eval można również użyć w niektórych przypadkach ostrożnie .

console.log(eval("true") === true) //true

Unikaj, evalponieważ może to być niebezpieczne. Preferuj JSON.parse("true").
Fred

1

Zwykle po prostu zapisuję wartość w LocalStore jako wartość logiczną, a następnie pobieram ją metodą parsowania, aby mieć pewność dla wszystkich przeglądarek. Poniższa metoda jest dostosowana do logiki biznesowej. Czasami mogę zapisać coś jako „nie” i nadal potrzebować falsew zamian

function toBoolean(str) {
    if (typeof str === 'undefined' || str === null) {
        return false;
    } else if (typeof str === 'string') {           
        switch (str.toLowerCase()) {
        case 'false':
        case 'no':
        case '0':
        case "":
            return false;
        default:
            return true;
        }
    } else if (typeof str === 'number') {
        return str !== 0
    }
    else {return 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.