无法在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? 

Answers:


69

Firefox的Storage实现只能存储字符串,但是2009年9月,W3C修改了草案以接受任何数据。实施(仍)尚未赶上请参见下面的编辑)。

因此,在您的情况下,布尔值将转换为字符串。

至于为什么"true" != true,如在MDC *中的Equal(==)描述中所写:

如果两个操作数的类型不同,则JavaScript会转换这些操作数,然后进行严格比较。如果操作数是数字或布尔值,则在可能的情况下将操作数转换为数字;否则,操作数将转换为数字。否则,如果一个操作数是一个字符串,则另一个操作数将转换为字符串(如果可能)。

请注意,该字符串将转换为Number而不是Boolean。由于"true"将转换为NaN,因此它将不等于任何值,因此false将其返回。

(*:有关实际标准,请参阅ECMA-262§11.9.3“抽象平等比较算法”)


编辑:setItem接口被恢复只接受在琴弦2011九月一日草案,以配合现有实现的行为,没有任何厂商有兴趣支持存储非字符串。有关详细信息,请参见https://www.w3.org/Bugs/Public/show_bug.cgi?id=12111


2
如果操作数是数字或布尔值,则如果可能,操作数将转换为数字 -我完全没有意识到这一点。我以为如果一个是字符串,另一个就被转换为字符串。干杯(+1)。
Andy E

2
@Andy,请查看有关此主题的有用说明
CMS 2010年

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 2014年

3
正确@AdonisK。但是,如果他在设置所有值时使用JSON.stringify,那么他就可以减轻将有效JSON输出到库的责任。那是一个非常稳定的库。
Colt McCormack 2015年

11

我的解决方案:

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

2
@koppor也许是因为如果getItem将返回布尔值,则此方法将产生错误的结果,因为true == 'true'is false
jox

8
..或localStorage.getItem(pre)==='true'没有其余部分的平原
phil294

1
@koppor为什么要投票?因为自以为是的堆积如山,字面上是:)
Ayyash

1
不需要“?true:false”,因为localStorage.getItem(pre)=='true'已经为您提供了布尔结果
FelipeDrumond

6

这与CMS的答案有关。

这是我一直使用的一个小功能来处理此问题的解析部分(该功能将在浏览器实现赶上规范后继续执行Right Thing,因此无需记住以后要更改代码):

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

1
与JSON.parse相比,这不是不必要的吗?JSON.parse(“ true”)和JSON.parse(true)都已经返回true,因此在浏览器实现boolean localstorage之后仍然会做正确的事
bscan

3

使用store.js

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

store.get('isUser')  //true

4
但是,是否真的有必要仅为这个简单的字符串到布尔转换任务包括整个库?
jayqui

1

我不确定LocalStorage是否可以保存布尔值,但是我可以告诉您,这样做时alert("true" == true);,它将永远不会评估为true,因为您隐式地将字符串与布尔值进行比较。这就是为什么要设置您true代替的布尔值的原因"true"


1
那么alert(“ 1” == 1)呢?Javascript是一种奇怪的(且不一致的)野兽。
支出者

@spender:这是因为将正确的操作数强制转换为用于比较的字符串。 "1" === 1实际上会返回false。
Andy E

@Kenny:哎呀facepalm,感谢您的纠正:-)我很困惑,因为布尔值转换为字符串。
安迪E

1

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

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

避免这样做,eval因为它可能不安全。更喜欢JSON.parse("true")
Fred

1

我通常要做的只是将值存储在LocalStore中为布尔值,然后使用解析方法进行检索,以确保适用于所有浏览器。下面的方法是针对我的业务逻辑定制的。有时我可能会将smth存储为“ no”,但仍然需要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;}
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.