localStorage.getItem( 'item')はlocalStorage.itemまたはlocalStorage ['item']よりも優れていますか?


84

最近、LocalStorageについて質問しました。アイテムがまだ設定されていないときに使用JSON.parse(localStorage.item)してJSON.parse(localStorage['item'])いて、戻るために機能しNULLていませんでした。

しかし、JSON.parse(localStorage.getItem('item')うまくいきました。そして、それはJSON.parse(localStorage.testObject || null)また機能します。

コメントの1つは基本的にそれを言ってlocalStorage.getItem()おり、localStorage.setItem()常に優先されるべきです:

ゲッターとセッターは、LS apiを操作するための一貫性のある、標準化されたクロスブラウザー互換の方法を提供し、他の方法よりも常に優先されるべきです。-クリストフ

localStorageに省略形のドットとブラケットの表記を使用するのが好きになりましたが、他の人がこれを採用していることを知りたいです。localStorage.getItem( 'item')はlocalStorage.itemまたはlocalStorage ['item']よりも優れていますか、それともそれらが機能する限り、省略表記で問題ありませんか?


クリストフは彼の推論を非常に明確にしたと思います。getItemそしてsetItem、物事を行うための標準化された方法です。
FABRICIOマット

1
そうですか。これらの推奨事項をざっと読むには少し眠すぎますが、このWebstorage APIは比較的新しいので、私は個人的に適切に文書化されたgetItem/setItemメソッドに固執します。仕様については後でもう一度読みますが、質問に答える唯一の失敗を防ぐ方法は、すべての主要なブラウザーでテストを行うことです。
FABRICIOマット

4
仕様には、「ストレージオブジェクトでサポートされているプロパティ名は、オブジェクトに関連付けられたリストに現在存在する各キーと値のペアのキーです」と記載されています。それもlocalStorage.item標準化されていませんか?
バーマー2012

2
@Barmar返信が少し遅れましたが、この質問の重複をたくさん見て、ここに戻ってきた後、あなたが絶対に正しいと返信します。ただし、これらのメソッドはオブジェクトの既存のプロパティと競合しないため、getItem/を再度使用することをお勧めします。例:動作しますが、localStorageのメソッドを上書きします。jsfiddle.net/DrquYsetItemlocalStoragelocalStorage.setItem('getItem', 'blah'); console.log(localStorage.getItem('getItem'));localStorage.getItem = 'blah';getItem
FABRICIOマット

1
私は、どちらのアプローチにも賛成する議論をまだ見ていません。名前と値のペアは、これまでどおりに実行されます。もう1つは、get / setメソッドを使用するときにnullを返します。オプションの値がnullである別の値のリストと比較する場合、一方は他方よりも理にかなっていると思いますが、両方が仕様に含まれている場合にどちらか一方が「優先」であると言うのはばかげています、IMO。両方のアプローチが利用可能になったのには理由があります。
Erik Reppen 2014

回答:


83

プロパティへの直接アクセス(localStorage.itemまたはlocalStorage['item'])と機能インターフェイスの使用(localStorage.getItem('item'))の両方が正常に機能します。どちらも標準であり、クロスブラウザと互換性があります。*仕様によると:

Storageオブジェクトでサポートされているプロパティ名は、オブジェクトに関連付けられたリストに現在存在する各キーと値のペアのキーであり、キーが最後にストレージ領域に追加された順序になっています。

要求された名前のキーと値のペアが見つからない場合は、動作が異なります。キーは、たとえば、'item'存在しない、var a = localStorage.item;もたらすaことundefinedながら、var a = localStorage.getItem('item');もたらすa値を有しますnull。あなたが発見したように、undefinedそしてnullJavaScript / EcmaScriptでは互換性がありません。:)

編集:クリストフが彼の答えで指摘しているように、関数型インターフェースは、の事前定義されたプロパティに等しいキーの下で値を確実に格納および取得する唯一の方法ですlocalStorage。(これらの6がありますlengthkeysetItemgetItemremoveItem、とclear。)ので、例えば、以下は常に仕事:

localStorage.setItem('length', 2);
console.log(localStorage.getItem('length'));

特に、最初のステートメントはプロパティに影響を与えないことに注意してくださいlocalStorage.length(キーが'length'まだにない場合はおそらくインクリメントすることを除いてlocalStorage)。この点で、仕様は内部的に一貫していないようです。

ただし、以下はおそらくあなたが望むことをしないでしょう:

localStorage.length = 2;
console.log(localStorage.length);

興味深いことに、1つ目はChromeでの操作なしですが、Firefoxでの機能呼び出しと同義です。2番目は、に存在するキーの数を常にログに記録しますlocalStorage

* これは、そもそもWebストレージをサポートするブラウザに当てはまります。(これには、ほとんどすべての最新のデスクトップおよびモバイルブラウザーが含まれます。)Cookieまたはその他の手法を使用してローカルストレージをシミュレートする環境では、動作は使用されるシムによって異なります。以下のためのいくつかのpolyfillsをlocalStorage見つけることができるここに


11

質問はすでにかなり古いですが、私は質問で引用されているので、私の発言について2つの言葉を言うべきだと思います。

ストレージオブジェクトはかなり特殊で、キーと値のペアのリストへのアクセスを提供するオブジェクトです。したがって、それは通常のオブジェクトや配列ではありません。

たとえば、長さ属性があります。これは、配列の長さ属性とは異なり、読み取り専用であり、ストレージ内のキーの数を返します。

配列を使用すると、次のことができます。

var a = [1,2,3,4];
a.length // => 4
a.length = 2;
a // => [1,2]

ここに、ゲッター/セッターを使用する最初の理由があります。というアイテムを設定したい場合はどうなり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()メソッドは、失敗に関してアトミックである必要があります。失敗した場合、メソッドは何もしません。つまり、データ記憶域への変更が成功するか、データ記憶域がまったく変更されないようにする必要があります。

理論的には、ゲッター/セッターと[]アクセスの間に違いはないはずですが、あなたは決して知りません...


最初の点で、JavaScriptのほとんどすべてが書き込み可能であり、localStorageAPIには私が知っている3つのプロパティしかありません。2つ目は、ドット表記または角かっこ表記のアプローチを使用すると、設定方法に関係なく値が文字列に自動変換されるため、同じセーフガードを使用できるため、何らかのネイティブセッターの実装が必要になります。クライアント側のブラウザシナリオで永続的な値が破損することは、実際に聞いたことがありません。バニラアクセサーでさえ、通常、何らかのセーフガードがあると思います。
Erik Reppen 2014

名前の衝突についてのポイントは優れています。lengthプロパティは、(ChromeとFirefoxで少なくとも[*])を呼び出す場合は変更されませんlocalStorage.setItem("length", something);が、あなたは取得することができsomethinglocalStorage.getItem("length");。興味深いことに、localStorage.length = something;Chromeでの割り当ては何もしませんが、Firefoxではsomethingキーの下に保存されます"length"(機能インターフェイスを使用してのみ取得できます)。[*]実際、Firefoxでは、lengthキーを押すとプロパティが変更されます"length"がまだにないれlocalStorageます。
テッドホップ2015年

@ ErikReppen-仕様によるとlocalStorage6つの定義済みの特性を有する:lengthkeygetItemsetItemremoveItem、およびclear
テッドホップ2015年

1

私はそれが古い投稿であることを知っていますが、実際にパフォーマンスについて言及した人は誰もいないので、それをベンチマークするためにいくつかのJsPerfテストを設定し、一貫性のあるインターフェイスでgetItemあり、setItemドット表記やブラケットを使用するよりも一貫して高速であり、読みやすくなっています。

これがJsPerfでの私のテストです


ur jsPerfは、テストに角かっこを含めませんでした。私はそれらを追加していくつかのテストを実行しました。パフォーマンスはブラウザベースです。ChromeとFirefoxの上の両方、getItemおよびsetItemドットは、Firefox上で最速であることクロームとブラケットに最速であることと、各カテゴリで最も遅いでした。また、「読みやすくなる」ことは完全に主観的だと思います...ええ、それはその実行する関数を述べていますが、オブジェクトまたは配列変数を扱ったことがある人なら誰でも、ドット/ブラケットで何が起こっているかを0.5秒で知るでしょう。
PlantTheIdea 2013年

そうです、これらのテストを書いている時点では、ゲッターとセッターはドット表記よりも一貫して高速でした。もうそうではありません。5分になったら、戻ってきてこの回答を更新します。それを指摘してくれてありがとう。
デイブマッキントッシュ2013年

0

すでに述べたように、存在しないキーを除いてほとんど違いはありません。パフォーマンスの違いは、異なるブラウザ/ OSを使用しているものに応じて。しかし、それは実際にはそれほど違いはありません。

標準のインターフェースを使用することをお勧めします。それが推奨される使用方法だからです。


「標準インターフェースを使用することをお勧めします」 -両方のインターフェースが標準で指定されています。
テッドホップ2014

@TedHopp標準ではsetItemとgetItemのみが指定されていると思います。
サルバドールダリ

2
それどころか。標準から:「ストレージオブジェクトでサポートされているプロパティ名は、キーがストレージ領域に最後に追加された順序で、オブジェクトに関連付けられたリストに現在存在する各キー/値ペアのキーです。」
テッドホップ2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.