Javascript localStorage.getItem('item')比localStorage.item或localStorage['item']好吗?

Javascript localStorage.getItem('item')比localStorage.item或localStorage['item']好吗?,javascript,syntax,local-storage,Javascript,Syntax,Local Storage,我最近问。使用JSON.parselocalStorage.item和JSON.parselocalStorage['item']在尚未设置项时无法返回NULL 但是,JSON.parselocalStorage.getItem'item'确实有效。事实证明,JSON.parselocalStorage.testObject | | null也可以工作 基本上说localStorage.getItem和localStorage.setItem应该始终是首选项: getter和setter提供了一

我最近问。使用JSON.parselocalStorage.item和JSON.parselocalStorage['item']在尚未设置项时无法返回NULL

但是,JSON.parselocalStorage.getItem'item'确实有效。事实证明,JSON.parselocalStorage.testObject | | null也可以工作

基本上说localStorage.getItem和localStorage.setItem应该始终是首选项:

getter和setter提供了一致的、标准化的 交叉浏览器兼容使用LS api的方式,并且应始终 比其他方式更受欢迎-


我开始喜欢在本地存储中使用速记点和括号符号,但我很想知道其他人对此的看法。localStorage.getItem'item'比localStorage.item或localStorage['item']好吗?或者只要它们有效,速记符号就可以了?

直接属性访问localStorage.item或localStorage['item']并使用功能接口localStorage.getItem'item'都可以。两者都是标准的,并且跨浏览器兼容。*根据:

存储对象上支持的属性名称是与该对象关联的列表中当前存在的每个密钥/值对的密钥,按照密钥上次添加到存储区域的顺序排列

当找不到具有请求名称的键/值对时,它们的行为不同。例如,如果键“item”不存在,则var a=localStorage.item;将导致a未定义,而var a=localStorage.getItem'item';将导致值为null的。正如您所发现的,未定义和null在JavaScript/EcmaScript中是不可互换的:

编辑:正如Christoph在中指出的,函数接口是可靠地存储和检索与localStorage预定义属性相同的键下的值的唯一方法。其中有六个:长度、键、setItem、getItem、removieItem和清除。因此,例如,以下各项始终有效:

localStorage.setItem('length', 2);
console.log(localStorage.getItem('length'));
请特别注意,第一条语句不会影响属性localStorage.length,除非在localStorage中没有键“length”时可能会增加它。在这方面,规范内部似乎不一致

但是,以下操作可能无法满足您的要求:

localStorage.length = 2;
console.log(localStorage.length);
有趣的是,第一个是Chrome中的no-op,但它与Firefox中的函数调用同义。第二个将始终记录localStorage中存在的密钥数


*这对于最初支持web存储的浏览器来说是正确的。这包括几乎所有现代桌面和移动浏览器。对于使用cookie或其他技术模拟本地存储的环境,行为取决于所使用的垫片。可以找到几个用于localStorage的PolyFill。

我知道这是一篇老文章,但由于没有人真正提到性能,我设置了一些JsPerf测试来对其进行基准测试,并且作为一个连贯的接口,getItem和setItem也始终比使用点符号或括号更快,而且更易于阅读


这里是我的测试

正如前面提到的,除了不存在的键之外,几乎没有区别。此选项取决于您使用的浏览器/操作系统。但其实没什么不同


我建议您使用标准界面,因为这是一种推荐的使用方式。

这个问题已经很老了,但由于问题中引用了我的话,我想我应该说两个字

存储对象相当特殊,它是一个对象,提供对键/值对列表的访问。因此,它不是一个普通的对象或数组

例如,它具有length属性,与array length属性不同,length属性是只读的,并返回存储器中的键数

使用阵列,您可以执行以下操作:

var a = [1,2,3,4];
a.length // => 4
a.length = 2;
a // => [1,2]
这里我们有使用getter/setter的第一个原因。如果要设置一个名为“长度”的项目,该怎么办

对于存储对象的其他成员,它甚至更为重要,因为它们是可写的,并且您可以意外地覆盖诸如getItem之类的方法。使用API方法可以防止任何这些可能的问题,并提供一致的接口

另一个有趣的点是我强调的规范中的以下段落:

setItem和removeItem方法在失败方面必须是原子的。在失败的情况下,该方法不执行任何操作。也就是说,对数据存储区域的更改必须是成功的,或者根本不能更改数据存储区域


从理论上讲,getter/setter和[]访问之间应该没有区别,但你永远不知道……

我相信Christoph已经把他的推理讲得很清楚了。getItem和setItem是做事的方式。我明白了。略读这些建议有点太困了,但由于这个webstorage API相对较新,我个人还是坚持使用p
适当记录的getItem/setItem方法。稍后我将再次阅读规范,但回答您问题的唯一防故障方法是在所有主要浏览器上进行测试。规范说,存储对象上支持的属性名称是当前与该对象关联的列表中每个键/值对的键。这不是也使localStorage.item标准化了吗?@Barmar的回答有点晚,但在看到这个问题的许多重复之后,回到这里,我会回答你是绝对正确的。但是,我建议再次使用getItem/setItem,因为这些方法不会与localStorage对象的现有属性冲突。示例:localStorage.setItem'getItem','blah';console.loglocalStorage.getItem'getItem';工作,而localStorage.getItem='blah';将覆盖localStorage的getItem方法。我仍然没有看到任何一种方法能让我信服。一个是名称/值对,就像它们一直以来一样。另一个在使用get/set方法时为空。我想,如果我与另一个可选值为null的值列表进行比较,其中一个比另一个更有意义,但在规范中同时使用其中一个或另一个是“首选”是愚蠢的,我认为。这两种方法都是有原因的。ur jsPerf在其测试中没有包含括号。我添加了它们并运行了一些测试,性能是基于浏览器的。在chrome和firefox上,getItem和setItem在每个类别中都是最慢的,在chrome上点是最快的,在firefox上括号是最快的。我还认为“更容易阅读”完全是主观的。。。是的,它说明了函数的执行情况,但是任何使用过对象或数组变量的人都会在半秒钟内知道点/括号发生了什么。你是对的,在编写这些测试时,getter和setter始终比dot notation快。不再是这样了。当我有5分钟的时间时,我会回来更新这个答案。感谢您指出这一点。我建议您使用标准接口-这两个接口都是在标准中指定的。@TedHopp我认为只有setItem和getItem是。相反。根据标准:存储对象上支持的属性名称是当前与该对象关联的列表中每个键/值对的键,按照键上次添加到存储区域的顺序。在第一点上,JavaScript中几乎所有东西都是可写的,而localStorage API只有我知道的三个属性。在第二种情况下,使用点或括号表示法仍然会遇到某种本机setter实现,因为无论如何设置,值都会自动转换为字符串,因此应该具有相同的可用保护措施。实际上,我以前从未听说过客户端浏览器场景中的持久值会损坏。我怀疑即使是普通的访问器通常也有某种保护措施。关于名称冲突的观点非常好。如果调用localStorage.setItemlength,则至少在Chrome和Firefox[*]中,length属性不会更改;,但是您可以使用localStorage.getItemlength;检索某些内容;。有趣的是,分配localStorage.length=something;在Chrome中是不可操作的,但在Firefox中,它将在密钥长度下存储一些内容,然后只能使用功能界面检索这些内容。[*]实际上,在Firefox中,如果密钥长度不在localStorage中,则length属性将更改。@ErikReppen-根据,localStorage有六个预定义属性:length、key、getItem、setItem、removeItem和clear。
localStorage.length = "foo";
localStorage.length  // => 0
localStorage.setItem("length","foo");
// the "length" key is now only accessable via the getter method:
localStorage.length  // => 1
localStorage.getItem("length") // => "foo"