【问题标题】:JS: Can "false" be type-coerced to false?JS:“假”可以强制类型为假吗?
【发布时间】:2011-09-29 07:20:49
【问题描述】:

当您使用 Html5 时,localStorage 值存储为字符串。如果您想存储复选框的状态然后在以后恢复它,这是您需要处理的事情。我希望这样的事情会起作用:

(function() {
  function e(id) { return document.getElementById(id); }

  e('save').addEventListener('click', function() {
   localStorage['check-value'] = e('checkbox').checked
  })
  e('checkbox').checked = localStorage['check-value'];
})();

但如果未选中该框并且字符串 "false" 在倒数第二行被强制类型转换为 true .我知道我可以做一些 if-test,但这是一个爱好项目,如果可能的话我想弄清楚。可以将"false" 强制转换为false 吗?

我没有为这个 btw 使用库,因为它是一个 chrome 扩展,我想让它保持轻量级。

【问题讨论】:

    标签: javascript type-coercion


    【解决方案1】:

    改变这一行:

    e('checkbox').checked = localStorage['check-value'];
    

    到这里:

    e('checkbox').checked = localStorage['check-value'] == "true";
    

    或者取决于你想要什么:

    e('checkbox').checked = localStorage['check-value'] != "false";
    

    如果您多次这样做,请将布尔本地存储访问封装在一个仅返回布尔值 true 或 false 的小函数中。

    function tfStr(val) {
        return(val === "true");
    }
    

    【讨论】:

      【解决方案2】:

      "false" 与其他字符串一样,只是一个字符串,您需要在此处自行检查。

      【讨论】:

      • 它与 "" 不同,后者是一个假值 :)
      • 确实,我想我应该说'false'没有特殊含义。
      【解决方案3】:

      您可以尝试使用JSON.parse 提取值。理想情况下,您还可以使用JSON.stringify 来序列化对象等。您可以通过将其抽象到其他接口后面来使其更易于管理。

      JSON.parse("false") == false
      

      包装器示例:

      var LocalStorageManager = new (function () {
         this.set = function (key, object) {
            localStorage[key] = JSON.stringify(object);
         };
      
         this.get = function (key) {
            return JSON.parse(localStorage[key]);
         };
      });
      

      【讨论】:

      • 我想说这可能会导致问题,但支持 localStorage 的浏览器也应该支持 JSON。
      • 是的,有这个想法。我想我宁愿不必调用 JSON.parse,因为这通常是一个 chrome 扩展,所以它会在每个页面上运行。
      • @George Mauer:试试看。除非您有大量数据,否则用户不太可能注意到来自JSON.parse 和朋友的任何小开销。
      • 那么这是否被推广为最佳实践?与其处理字符串转换,不如将所有内容存储在单个 json 序列化对象中,并且只有在遇到性能问题时才将其拉出?
      • @George Mauer:这取决于您存储的值。如果您不存储任何复杂的数据结构(即您坚持使用数字和布尔值之类的原语),这可能是矫枉过正,您可以通过以典型方式转换它们来做到这一点。最后,就我个人而言,我认为这个解决方案更健壮、更易于使用且更易于维护。当然,它可能比其他一些方法慢一点,但是解析 JSON(尤其是像这样的简单值)已经非常快了。
      【解决方案4】:

      你可以测试它是否等于字符串“false”:

      e('checkbox').checked = localStorage['check-value'] != 'false';
      

      或者,您可以在存储之前和检索之后将其强制转换为一个数字:

      localStorage['check-value'] = +e('checkbox').checked
      // ...
      e('checkbox').checked = +localStorage['check-value']
      

      【讨论】:

      • 我在想一些类似于强制数字的东西,但我认为您的代码在控制台输出 NaN 中不会工作 var str = "false"; +str;
      • 它强制它两次。所以在你存储它之前,false 被翻译成0。然后,当您检索它时,字符串 "0" 被强制转换为数字 0,JavaScript 将其转换为 false
      【解决方案5】:

      你不能在 JS 上真正做到这一点。你应该使用var boolValue = (stringValue !== 'false') 或任何漂浮在你船上的东西。

      【讨论】:

        【解决方案6】:

        只是在这里重复,但你可以做一些真的愚蠢的事情,比如

        eval(localStorage['check-value'])

        如果字符串为假,它将评估为布尔假。显然你不想这样做,因为它是一个主要的安全漏洞。

        您也可以使用三元运算符:

        (localStorage['check-value']==="false")?false:localStorage['check-value'];

        【讨论】:

        • 嗯,这很有趣——这会是一个安全漏洞吗?我不清楚 localStorage 规则,但似乎唯一的东西就是你的域上的代码放置在那里的东西。因此,如果恶意代码位于 localStorage 中,则意味着它已经有机会运行并造成损害……我的推理是否错了?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-05-05
        • 2011-07-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-15
        相关资源
        最近更新 更多