Javascript localStorage.getItem('item') 是否比 localStorage.item 或 localStorage['item'] 好?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12632463/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is localStorage.getItem('item') better than localStorage.item or localStorage['item']?
提问by Mark Rummel
I recently asked a question about LocalStorage. Using JSON.parse(localStorage.item)
and JSON.parse(localStorage['item'])
weren't working to return NULL
when the item hadn't been set yet.
我最近问了一个关于 LocalStorage 的问题。当项目尚未设置时,使用JSON.parse(localStorage.item)
并且JSON.parse(localStorage['item'])
无法返回NULL
。
However, JSON.parse(localStorage.getItem('item')
did work. And it turns out, JSON.parse(localStorage.testObject || null)
also works.
但是,JSON.parse(localStorage.getItem('item')
确实有效。事实证明,它JSON.parse(localStorage.testObject || null)
也有效。
One of the commentsbasically said that localStorage.getItem()
and localStorage.setItem()
should always be preferred:
其中一条评论基本上是说localStorage.getItem()
并且localStorage.setItem()
应该始终是首选:
The getter and setter provide a consistent, standardised and crossbrowser compatible way to work with the LS api and should always be preferred over the other ways. -Christoph
getter 和 setter 提供了一种一致的、标准化的和跨浏览器兼容的方式来使用 LS api,并且应该始终优先于其他方式。-克里斯托夫
I've come to like using the shorthand dot and bracket notations for localStorage, but I'm curious to know others' take on this. Is localStorage.getItem('item') better than localStorage.item or localStorage['item'] OR as long as they work are the shorthand notations okay?
我开始喜欢对 localStorage 使用速记点和括号符号,但我很想知道其他人对此的看法。localStorage.getItem('item') 是否比 localStorage.item 或 localStorage['item'] 更好,或者只要它们有效,速记符号就可以吗?
回答by Ted Hopp
Both direct property access (localStorage.item
or localStorage['item']
) and using the functional interface (localStorage.getItem('item')
) work fine. Both are standard and cross-browser compatible.*According to the spec:
直接属性访问 (localStorage.item
或localStorage['item']
) 和使用功能接口 ( localStorage.getItem('item')
) 都可以正常工作。两者都是标准的和跨浏览器兼容的。*根据规格:
The supported property names on a Storage object are the keys of each key/value pair currently present in the list associated with the object, in the order that the keys were last added to the storage area.
Storage 对象上支持的属性名称是当前存在于与该对象关联的列表中的每个键/值对的键,按照键最后添加到存储区域的顺序。
They just behave differently when no key/value pair is found with the requested name. For example, if key 'item'
does not exist, var a = localStorage.item;
will result in a
being undefined
, while var a = localStorage.getItem('item');
will result in a
having the value null
. As you have discovered, undefined
and null
are not interchangeable in JavaScript/EcmaScript. :)
当没有找到具有请求名称的键/值对时,它们的行为会有所不同。例如,如果 key'item'
不存在,var a = localStorage.item;
将导致a
is undefined
,而var a = localStorage.getItem('item');
将导致a
具有 value null
。正如你所发现的,undefined
而null
不是在JavaScript / EcmaScript的互换。:)
EDIT:As Christoph points out in his answer, the functional interface is the only way to reliably store and retrieve values under keys equal to the predefined properties of localStorage
. (There are six of these: length
, key
, setItem
, getItem
, removeItem
, and clear
.) So, for instance, the following will always work:
编辑:正如 Christoph 在他的回答中指出的那样,函数式接口是在等于 的预定义属性的键下可靠地存储和检索值的唯一方法localStorage
。(其中有六个:length
、key
、setItem
、getItem
、removeItem
和clear
。)因此,例如,以下内容将始终有效:
localStorage.setItem('length', 2);
console.log(localStorage.getItem('length'));
Note in particular that the first statement will not affect the property localStorage.length
(except perhaps incrementing it if there was no key 'length'
already in localStorage
). In this respect, the spec seems to be internally inconsistent.
请特别注意,第一个语句不会影响物业localStorage.length
(如果没有按键,除了可能增加它'length'
已经localStorage
)。在这方面,规范似乎在内部不一致。
However, the following will probably not do what you want:
但是,以下内容可能不会执行您想要的操作:
localStorage.length = 2;
console.log(localStorage.length);
Interestingly, the first is a no-op in Chrome, but is synonymous with the functional call in Firefox. The second will always log the number of keys present in localStorage
.
有趣的是,第一个是 Chrome 中的无操作,但与 Firefox 中的函数调用同义。第二个将始终记录localStorage
.
*This is true for browsers that support web storage in the first place. (This includes pretty much all modern desktop and mobile browsers.) For environments that simulate local storage using cookies or other techniques, the behavior depends on the shim that is used. Several polyfills for localStorage
can be found here.
*这对于首先支持 Web 存储的浏览器来说是正确的。(这几乎包括所有现代桌面和移动浏览器。)对于使用 cookie 或其他技术模拟本地存储的环境,行为取决于所使用的 shim。localStorage
可以在这里找到几个 polyfills 。
回答by Christoph
The question is already quite old, but since I have been quoted in the question, I think I should say two words about my statement.
这个问题已经很老了,但既然问题中引用了我,我想我应该就我的陈述说两句。
The Storage Object is rather special, it's an object, which provides access to a list of key/value pairs. Thus it's not an ordinary object or array.
存储对象相当特殊,它是一个对象,它提供对键/值对列表的访问。因此它不是一个普通的对象或数组。
For example it has the length attribute, which unlike the array length attribute is readonly and returns the number of keys in the storage.
例如它有长度属性,它不像数组长度属性是只读的,它返回存储中的键数。
With an array you can do:
使用数组,您可以执行以下操作:
var a = [1,2,3,4];
a.length // => 4
a.length = 2;
a // => [1,2]
Here we have the first reason to use the getters/setters. What if you want to set an item called length
?
在这里,我们有第一个使用 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"
With other members of the Storage object it's even more critical, since they are writable and you can accidently overwrite methods like getItem
. Using the API methods prevents any of these possible problems and provides a consistent Interface.
对于 Storage 对象的其他成员,这更加重要,因为它们是可写的,并且您可能会意外地覆盖getItem
. 使用 API 方法可以防止任何这些可能的问题并提供一致的接口。
Also interesting point is the following paragraph in the spec (emphasized by me):
同样有趣的一点是规范中的以下段落(我强调):
The setItem() and removeItem() methods must be atomic with respect to failure.In the case of failure, the method does nothing. That is, changes to the data storage area must either be successful, or the data storage area must not be changed at all.
setItem() 和 removeItem() 方法对于失败必须是原子的。在失败的情况下,该方法什么也不做。也就是说,对数据存储区的更改必须成功,或者根本不能更改数据存储区。
Theoretically there should be no difference between the getters/setters and the []
access, but you never know...
理论上,getter/setter 和[]
访问之间应该没有区别,但你永远不知道......
回答by Dave Mackintosh
I know it's an old post but since nobody actually mentioned performance I set up some JsPerf tests to benchmark it and as well as being a coherent interface getItem
and setItem
are also consistently faster than using dot notation or brackets as well as being much easier to read.
我知道这是一篇旧帖子,但由于没有人真正提到性能,我设置了一些 JsPerf 测试来对其进行基准测试,并且作为一个连贯的界面getItem
,setItem
并且始终比使用点符号或括号更快,并且更容易阅读。
Here are my tests on JsPerf
这是我对 JsPerf 的测试
回答by Salvador Dali
As it was mentioned, there is almost no difference except of nonexisting key. The difference in performance variesdepending on what browser/OS are you using. But it is not really that different.
如前所述,除了不存在的密钥外,几乎没有区别。在性能差而变化取决于/ OS,你使用的是什么浏览器。但实际上并没有那么不同。
I suggest you to use standard interface, just because it is a recommended way of using it.
我建议你使用标准接口,因为这是一种推荐的使用方式。