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.parse(localStorage.item)和JSON.parse(localStorage['item'])无法在项目尚未设置时返回NULL 然而,JSON.parse(localStorage.getItem('item')确实有效。结果证明,JSON.parse(localStorage.testObject | null)也有效 基本上说,localStorage.getItem()和localStorage.setItem()应该始终是首选: getter和

我最近问。使用
JSON.parse(localStorage.item)
JSON.parse(localStorage['item'])
无法在项目尚未设置时返回
NULL

然而,
JSON.parse(localStorage.getItem('item')
确实有效。结果证明,
JSON.parse(localStorage.testObject | null)
也有效

基本上说,
localStorage.getItem()
localStorage.setItem()
应该始终是首选:

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


我开始喜欢在localStorage中使用速记点和括号符号,但我很想知道其他人对此的看法。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'))
将导致
a
具有值
null
。正如您所发现的,
未定义的
null
在JavaScript/EcmaScript中是不可互换的

EDIT:正如Christoph在中指出的那样,功能接口是可靠地存储和检索与
localStorage
预定义属性相同的键下的值的唯一方法。(其中有六种:
length
key
setItem
getItem
removietem
clear
)因此,例如,以下操作将始终有效:

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的第一个原因。如果您想设置一个名为
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"
对于存储对象的其他成员,它甚至更为重要,因为它们是可写的,并且您可以意外地覆盖方法,如
getItem
。使用API方法可以防止这些可能的问题,并提供一致的接口

同样有趣的是规范中的以下段落(我强调):

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


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

我相信Christoph已经把他的推理说得很清楚了。
getItem
setItem
是做事的方式。我明白了。我有点困了,不想浏览这些建议,但由于这个webstorage API相对较新,我个人会坚持正确记录的
getItem
/
setItem
方法。稍后我将再次阅读规范,但回答您问题的唯一防故障方法是在所有主要浏览器上进行测试。规范说“存储对象上支持的属性名称是当前与该对象关联的列表中的每个键/值对的键。”这难道不是我的代码吗