【问题标题】:Cannot set boolean values in LocalStorage?无法在 LocalStorage 中设置布尔值?
【发布时间】:2010-07-16 08:33:05
【问题描述】:

我注意到我无法在 localStorage 中设置布尔值?

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

当我尝试测试 localStorage.getItem("item1") == "true" 时总是提示 true | false 它提示 true ... 如何将 localStorage 中的项目设置为 true?

即使是字符串,我以为只有=== 会检查类型?

所以

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

【问题讨论】:

    标签: javascript


    【解决方案1】:

    目前,Safari、WebKit、Chrome、FirefoxIE 的所有实现都遵循 WebStorage 标准的the current version,其中存储项的值只能是字符串。

    一个选项是使用 JSON parsestringify 方法来序列化反序列化数据,正如我前段时间在another question 中建议的那样,例如:

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

    【讨论】:

    • 如果传入value的字符串不是有效的JSON(例如JSON.parse("a random string")),这显然会中断
    • 真@AdonisK。但是,如果他在设置所有值时使用 JSON.stringify,那么他就能够卸载将有效 JSON 输出到库的责任。这是一个非常稳定的库。
    • current specification 定义了一个接口,其中getItem 只返回一个字符串或nullsetItem 只接受一个字符串。阅读other answer,这似乎不会改变,所以这个答案中的措辞已经过时了。
    • 是的——它不是版本,它是唯一的版本。
    【解决方案2】:

    Firefox's implementation of Storage 只能存储字符串,但在2009 September 上,W3C 修改了草案以接受任何数据。 实现(仍然)还没有赶上见下面的编辑)。

    所以在你的情况下,布尔值被转换为字符串。

    至于为什么"true" != true,写在the description of Equal (==) in MDC*:

    如果两个操作数的类型不同,JavaScript 会转换操作数,然后应用严格比较。如果任一操作数是数字或布尔值,则操作数将尽可能转换为数字;否则,如果任一操作数是字符串,则尽可能将另一个操作数转换为字符串。

    请注意,字符串被转换为 Number 而不是 Boolean。由于"true"转换为数字是NaN,所以它不会等于任何东西,所以返回false

    (*: 实际标准见 ECMA-262 §11.9.3 “抽象等式比较算法”)


    编辑:setItem 接口已恢复为仅在 2011 Sept 1st draft 上接受字符串以匹配现有实现的行为,因为没有供应商对支持存储非字符串感兴趣。有关详细信息,请参阅https://www.w3.org/Bugs/Public/show_bug.cgi?id=12111

    【讨论】:

    • 如果任一操作数是数字或布尔值,则操作数将尽可能转换为 数字 - 我完全没有意识到这一点。我想如果一个是字符串,另一个被转换成字符串。干杯(+1)。
    • @Andy,检查这个useful notes的主题。
    【解决方案3】:

    我的解决方案:

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

    【讨论】:

    • @koppor 也许是因为如果 getItem 会返回一个布尔值,那么这个方法会产生错误的结果,因为 true == 'true'false
    • ..或普通的localStorage.getItem(pre)==='true' 没有其余部分
    • @koppor 为什么这被否决了?因为自以为是的堆垛机正在溢出,从字面上看:)
    • "? true : false" 是不必要的,因为 localStorage.getItem(pre) == 'true' 已经给你一个布尔结果
    【解决方案4】:

    这与CMS的回答有关。

    这是我一直用来处理此问题的解析部分的一个小函数(在浏览器实现赶上规范后,该函数将继续做正确的事情,因此无需记住稍后更改代码) :

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

    【讨论】:

    • 与 JSON.parse 相比,这不是没有必要吗? JSON.parse("true") 和 JSON.parse(true) 都已经返回 true,所以在浏览器实现 boolean localstorage 之后仍然会做正确的事情
    【解决方案5】:

    我想指出,将纯布尔值包装在对象中可能会更容易,然后使用JSON.stringify 创建本地存储内容和其他方式,JSON.parse 来检索它:

    let storeMe = {
      myBool: true
    }
    
    localStorage.setItem('test', JSON.stringify(storeMe))
    let result = JSON.parse(localStorage.getItem('test'))
    
    

    【讨论】:

      【解决方案6】:

      使用store.js:

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

      store.get('isUser')  //true
      

      【讨论】:

      • 但是真的有必要为了这个简单的字符串到布尔转换任务而包含一个完整的库吗?
      【解决方案7】:

      我通常所做的只是将 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;}
      }
      

      【讨论】:

        【解决方案8】:

        我不确定 LocalStorage 是否可以保存布尔值,但我可以告诉您,当您执行 alert("true" == true); 时,它永远不会评估为 true,因为您正在隐式地将字符串与布尔值进行比较。这就是为什么设置布尔值时使用true 而不是"true"

        【讨论】:

        • alert("1"==1) 呢? Javascript 是一个奇怪(且不一致)的野兽。
        • @spender:这是因为右操作数被转换为字符串进行比较。 "1" === 1 实际上会返回 false。
        • @Kenny: 哎呀facepalm,感谢您的更正 :-) 由于布尔值转换为字符串的方式,我搞混了。
        【解决方案9】:

        eval在某些情况下也可以谨慎使用

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

        【讨论】:

        • 避免使用eval,因为它可能不安全。首选JSON.parse("true")
        猜你喜欢
        • 2012-10-12
        • 2019-10-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-01
        • 2014-06-29
        • 1970-01-01
        相关资源
        最近更新 更多