我最近问过a question about LocalStorage。当项目尚未设置时,使用JSON.parse(localStorage.item)
和JSON.parse(localStorage['item'])
无法返回NULL
。
然而,JSON.parse(localStorage.getItem('item')
确实有效。结果证明,JSON.parse(localStorage.testObject || null)
也有效。
One of the comments基本上说应始终首选localStorage.getItem()
和localStorage.setItem()
:
getter和setter提供一致,标准化和 与LS api一起工作的crossbrowser兼容方式应始终如此 比其他方式更受欢迎。 - Christoph
我喜欢使用localStorage的简写点和括号表示法,但我很想知道其他人对此的看法。 localStorage.getItem('item')是否优于localStorage.item或localStorage ['item']或者只要它们有效,是否可以使用简写符号?
答案 0 :(得分:72)
直接属性访问(localStorage.item
或localStorage['item']
)和使用功能界面(getItem('item')
)都可以正常工作。两者都是标准的和跨浏览器兼容。 * 根据the spec:
Storage对象上支持的属性名称是当前与对象关联的列表中存在的每个键/值对的键,按键上次添加到存储区域的顺序。
当没有找到具有所请求名称的键/值对时,它们的行为会有所不同。例如,如果密钥'item'
不存在,var a = localStorage.item;
将导致a
为undefined
,而var a = localStorage.getItem('item');
将导致a
拥有密钥null
价值undefined
。正如您所发现的,null
和localStorage
在JavaScript / EcmaScript中不可互换。 :)
编辑:正如Christoph在his answer中指出的那样,功能界面是在length
的预定义属性下可靠地存储和检索值的唯一方法( key
,setItem
,getItem
,removeItem
,clear
和localStorage.setItem('length', 2);
console.log(localStorage.getItem('length'));
)。因此,例如,以下内容将始终有效:
localStorage.length
请特别注意,第一个语句不会影响属性'length'
(如果localStorage
中已经没有键localStorage.length = 2;
console.log(localStorage.length);
,则可能会增加它)。在这方面,规范似乎内部不一致。
但是,以下内容可能无法达到您想要的效果:
localStorage
有趣的是,第一个是Chrome中的no-op,但它与Firefox中的函数调用同义。第二个将始终记录localStorage
中的密钥数。
* 首先支持Web存储的浏览器也适用。 (这包括几乎所有现代桌面和移动浏览器。)对于使用cookie或其他技术模拟本地存储的环境,行为取决于所使用的垫片。可以找到{{1}}的几个填充here。
答案 1 :(得分:10)
这个问题已经很老了,但自从我在问题中被引用以来,我想我应该对我的陈述说两句话。
存储对象相当特殊,它是一个对象,可以访问键/值对列表。因此,它不是普通的对象或数组。
例如,它具有length属性,与数组长度属性不同,它是readonly并返回存储中的键数。
使用数组,您可以:
var a = [1,2,3,4];
a.length // => 4
a.length = 2;
a // => [1,2]
这里我们有第一个使用getter / setter的原因。如果您要设置名为length
的项目
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"
对于Storage对象的其他成员来说,它更加重要,因为它们是可写的,您可能会意外地覆盖getItem
之类的方法。使用API方法可以防止出现任何这些可能的问题,并提供一致的接口。
同样有趣的一点是规范中的以下段落(我强调):
setItem()和removeItem()方法在失败方面必须是原子的。在失败的情况下,该方法不执行任何操作。也就是说,对数据存储区域的更改必须成功,否则根本不能更改数据存储区域。
从理论上讲,getter / setter和[]
访问之间应该没有区别,但你永远不会知道......
答案 2 :(得分:1)
我知道这是一个老帖子,但由于没有人真正提到性能我设置了一些JsPerf测试来对其进行基准测试,并且作为一个连贯的接口getItem
和setItem
也始终比使用点更快符号或括号以及更容易阅读。
以下是我的测试on JsPerf
答案 3 :(得分:0)
如前所述,除了不存在的密钥之外几乎没有区别。 difference in performance varies取决于您使用的浏览器/操作系统。但它并没有那么不同。
我建议您使用标准界面,因为它是推荐的使用方式。