LocalStorageにブール値を設定できませんか?


112

にブール値を設定できないことに気付きましたlocalStorageか?

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

true | falseテストしようとしたときに常に警告localStorage.getItem("item1") == "true"trueの警告...アイテムlocalStorageをtrue に設定するにはどうすればよいですか?

文字列だって===タイプだけチェックするのかな?

そう

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

回答:


69

FirefoxのStorageの実装は文字列のみを保存できますが、2009年9月に、W3Cはすべてのデータを受け入れるようにドラフトを変更しました。(まだ)実装はまだ追いついていません以下の編集を参照してください)。

したがって、あなたの場合、ブール値は文字列に変換されます。

理由については、MDCのEqual()の説明に記載"true" != trueされているように== *:

2つのオペランドが同じタイプでない場合、JavaScriptはオペランドを変換してから、厳密な比較を適用します。いずれかのオペランドが数値またはブール値の場合、オペランドは可能であれば数値に変換されます。それ以外の場合、どちらかのオペランドが文字列の場合、可能であれば、もう一方のオペランドは文字列に変換されます。

文字列はブール値ではなく数値に変換されることに注意してください。数値に変換されるので、それは何にも等しくないので、返されます。"true"NaNfalse

(*:実際の規格については、ECMA-262§11.9.3「抽象等値比較アルゴリズム」を参照)


編集:setItemインターフェイスだけで文字列を受け入れるように戻った2011年9月1日のドラフトのベンダーのいずれも非文字列を格納支援に興味を持っていないされているように、既存の実装の動作と一致します。詳細については、https://www.w3.org/Bugs/Public/show_bug.cgi?id = 12111を参照してください


2
どちらかのオペランドが数値またはブール値の場合、オペランドは可能であれば数値に変換されます -私はそれを完全に理解していませんでした。私は、1つがストリングである場合、もう1つはストリングにキャストされると考えました。乾杯(+1)。
アンディE

2
@Andy、件名に関するこの有用なメモを確認してください。
CMS

91

現時点では、Safari、WebKit、Chrome、FirefoxIEのすべての実装は、WebStorage標準の古いバージョンに従っており、ストレージ項目の値は文字列のみにすることができます。

オプションは、JSON parsestringifyメソッドを使用してデータをシリアルおよび逆シリアル化することです。たとえば、先に別の質問で提案しました。

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

4
渡された文字列がvalue有効なJSON(たとえばJSON.parse("a random string"))ではない場合、これは明らかに壊れます
Adonis K. Kakoulidis

3
真の@AdonisK。ただし、すべての値を設定するときにJSON.stringifyを使用している場合は、有効なJSONをライブラリに出力する責任をオフロードできます。そして、それは非常に安定したライブラリです。
コルトマコーマック

11

私の解決策:

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

2
@kopporたぶんのgetItemが今までブール値を返すかどう以来、このメソッドは、誤った結果が得られますのでtrue == 'true'ですfalse
jox

8
..またはlocalStorage.getItem(pre)==='true'残りのない平野
phil294

1
@kopporなぜこれは反対投票ですか?独善的なスタッカーが溢れているため、文字通り:)
Ayyash

1
"?true:false"は不要です
。localStorage.getItem

6

これはCMSの回答に関連しています。

これは、この問題の解析部分を処理するために使用していた小さな関数です(この関数は、ブラウザーの実装が仕様に追いついた後も正しいことを実行し続けるので、後でコードを変更することを覚えておく必要はありません)。

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

1
JSON.parseと比較して、これは不要ではありませんか?JSON.parse( "true")とJSON.parse(true)はどちらもすでにtrueを返すため、ブラウザーがブールローカルストレージを実装した後でも正しく動作します
bscan

3

store.jsを使用します

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

store.get('isUser')  //true

4
しかし、この単純な文字列からブール値への変換タスクのためだけにライブラリ全体を含める必要があるのでしょうか?
ジェイキ

1

LocalStorageがブール値を保存できるかどうかはわかりませalert("true" == true);んが、暗黙的に文字列とブール値を比較しているので、保存してもtrueと評価されないことはわかります。これが、のtrue代わりに使用するブール値を設定する理由です"true"


1
alert( "1" == 1)はどうですか?JavaScriptは奇妙な(そして一貫性のない)野獣です。
10

@spender:これは、比較のために右側のオペランドが文字列にキャストされるためです。 "1" === 1実際にはfalseを返します。
アンディE

@Kenny:おっとfacepalm、訂正ありがとうございます:-)ブール値が文字列にキャストされる方法が原因で混乱しました。
アンディE

1

eval場合によっては慎重に使用することもできます。

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

eval安全ではない可能性があるため、避けてください。好むJSON.parse("true")
フレッド

1

私が通常行うことは、LocalStoreの値をブール値として保存し、解析メソッドを使用して取得することです。これは、すべてのブラウザーで確実に行うためです。以下のメソッドは、ビジネスロジック用にカスタマイズされています。時々、Smthを「いいえ」として保存してもfalse、見返りに必要になることがあります

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;}
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.