Ist localStorage.getItem ('item') besser als localStorage.item oder localStorage ['item']?

83

Ich habe kürzlich eine Frage zu LocalStorage gestellt . Verwenden JSON.parse(localStorage.item)und JSON.parse(localStorage['item'])arbeiteten nicht, um zurückzukehren, NULLwenn der Artikel noch nicht eingestellt war.

Hat JSON.parse(localStorage.getItem('item')aber funktioniert. Und es stellt sich heraus, JSON.parse(localStorage.testObject || null)funktioniert auch.

Einer der Kommentare sagte im Grunde, dass localStorage.getItem()und localStorage.setItem()sollte immer bevorzugt werden:

Der Getter und der Setter bieten eine konsistente, standardisierte und Crossbrowser-kompatible Möglichkeit, mit der LS-API zu arbeiten, und sollten immer den anderen Methoden vorgezogen werden. - Christoph

Ich mag es, die Kurz- und Klammernotationen für localStorage zu verwenden, aber ich bin gespannt, wie andere dies angehen. Ist localStorage.getItem ('item') besser als localStorage.item oder localStorage ['item'] ODER sind die Kurzschreibweisen in Ordnung, solange sie funktionieren?

Mark Rummel
quelle
Ich glaube, Christoph hat seine Argumentation ganz klar gemacht. getItemund setItemsind die standardisierte Art, Dinge zu tun.
Fabrício Matté
1
Aha. Wenig zu schläfrig durch diese Empfehlungen zu überfliegen, aber da dies WebStorage API relativ neu ist, würde ich persönlich mit den ordnungsgemäß dokumentiert Stick getItem/ setItemMethoden. Ich werde die technischen Daten später noch einmal lesen, aber die einzige ausfallsichere Möglichkeit, Ihre Frage zu beantworten, besteht darin, sie während aller Tests in allen gängigen Browsern zu testen.
Fabrício Matté
4
In der Spezifikation heißt es: "Die unterstützten Eigenschaftsnamen in einem Speicherobjekt sind die Schlüssel jedes Schlüssel / Wert-Paares, das derzeit in der dem Objekt zugeordneten Liste vorhanden ist." Ist das nicht auch localStorage.itemstandardisiert?
Barmar
2
@Barmar Eine etwas späte Antwort, aber nachdem ich so viele Dupes dieser Frage gesehen habe und hierher zurückgekommen bin, werde ich antworten, dass Sie absolut Recht haben. Ich empfehle jedoch erneut, getItem/ zu verwenden, setItemda diese Methoden nicht mit den vorhandenen Eigenschaften des localStorageObjekts in Konflikt stehen . Beispiel: Funktioniert localStorage.setItem('getItem', 'blah'); console.log(localStorage.getItem('getItem'));, während localStorage.getItem = 'blah';die getItemMethode von localStorage überschrieben wird. jsfiddle.net/DrquY
Fabrício Matté
1
Ich habe immer noch kein Argument für einen der beiden Ansätze gesehen, das mich überzeugt hat. Man macht Name / Wert-Paare wie immer. Der andere gibt uns Nullen, wenn wir get / set-Methoden verwenden. Ich nehme an, wenn ich mit einer anderen Liste von Werten vergleichen würde, die für die optionalen Werte null hatten, wäre einer sinnvoller als der andere, aber zu sagen, dass der eine oder andere "bevorzugt" ist, wenn beide in der Spezifikation sind, ist dumm, IMO. Beide Ansätze wurden aus einem bestimmten Grund zur Verfügung gestellt.
Erik Reppen

Antworten:

83

Sowohl der direkte Zugriff auf Eigenschaften ( localStorage.itemoder localStorage['item']) als auch die Verwendung der Funktionsschnittstelle ( localStorage.getItem('item')) funktionieren einwandfrei. Beide sind Standard- und browserübergreifend kompatibel. * Gemäß der Spezifikation :

Die unterstützten Eigenschaftsnamen in einem Speicherobjekt sind die Schlüssel jedes Schlüssel / Wert-Paares, das derzeit in der dem Objekt zugeordneten Liste vorhanden ist, in der Reihenfolge, in der die Schlüssel zuletzt zum Speicherbereich hinzugefügt wurden.

Sie verhalten sich nur anders, wenn kein Schlüssel / Wert-Paar mit dem angeforderten Namen gefunden wird. Zum Beispiel, wenn Schlüssel 'item'nicht vorhanden ist , var a = localStorage.item;wird in Folge asein undefined, während var a = localStorage.getItem('item');in Folge wird amit dem Wert null. Wie Sie festgestellt haben undefinedund nullin JavaScript / EcmaScript nicht austauschbar sind. :) :)

BEARBEITEN: Wie Christoph in seiner Antwort hervorhebt , ist die funktionale Schnittstelle die einzige Möglichkeit, Werte unter Schlüsseln, die den vordefinierten Eigenschaften von entsprechen, zuverlässig zu speichern und abzurufen localStorage. (Es gibt sechs davon: length, key, setItem, getItem, removeItem, und clear.) So zum Beispiel der folgende wird immer funktionieren:

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

Beachten Sie insbesondere , dass die erste Aussage wird die Eigenschaft nicht beeinflussen localStorage.length(außer vielleicht es erhöht wird, wenn kein Schlüssel ist 'length'bereits in localStorage). In dieser Hinsicht scheint die Spezifikation intern inkonsistent zu sein.

Folgendes wird jedoch wahrscheinlich nicht das tun, was Sie wollen:

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

Interessanterweise ist das erste ein No-Op in Chrome, aber es ist gleichbedeutend mit dem Funktionsaufruf in Firefox. Der zweite protokolliert immer die Anzahl der vorhandenen Schlüssel localStorage.

* Dies gilt für Browser, die in erster Linie Webspeicher unterstützen. (Dies schließt so ziemlich alle modernen Desktop- und mobilen Browser ein.) In Umgebungen, in denen lokaler Speicher mithilfe von Cookies oder anderen Techniken simuliert wird, hängt das Verhalten von der verwendeten Shim ab. Mehrere polyfills für localStoragefinden sich hier .

Ted Hopp
quelle
11

Die Frage ist schon ziemlich alt, aber da ich in der Frage zitiert wurde, denke ich, ich sollte zwei Worte über meine Aussage sagen.

Das Speicherobjekt ist etwas Besonderes, es ist ein Objekt, das Zugriff auf eine Liste von Schlüssel / Wert-Paaren bietet. Es ist also kein gewöhnliches Objekt oder Array.

Zum Beispiel hat es das Längenattribut, das im Gegensatz zum Array-Längenattribut schreibgeschützt ist und die Anzahl der Schlüssel im Speicher zurückgibt.

Mit einem Array können Sie Folgendes tun:

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

Hier haben wir den ersten Grund, die Getter / Setter zu verwenden. Was ist, wenn Sie ein Element mit dem Namen festlegen möchten 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"

Bei anderen Mitgliedern des Speicherobjekts ist dies sogar noch kritischer, da sie beschreibbar sind und Sie versehentlich Methoden wie überschreiben können getItem. Die Verwendung der API-Methoden verhindert eines dieser möglichen Probleme und bietet eine konsistente Schnittstelle.

Interessant ist auch der folgende Absatz in der Spezifikation (von mir hervorgehoben):

Die Methoden setItem () und removeItem () müssen in Bezug auf Fehler atomar sein. Im Fehlerfall führt die Methode nichts aus. Das heißt, Änderungen am Datenspeicherbereich müssen entweder erfolgreich sein oder der Datenspeicherbereich darf überhaupt nicht geändert werden.

Theoretisch sollte es keinen Unterschied zwischen den Gettern / Setzern und dem []Zugang geben, aber man weiß nie ...

Christoph
quelle
Zum ersten Punkt ist fast alles in JavaScript beschreibbar und die localStorage-API hat nur drei mir bekannte Eigenschaften. Auf der zweiten Seite treffen Sie bei Verwendung der Punkt- oder Klammer-Notationsansätze immer noch auf eine Art native Setter-Implementierung, da die Werte automatisch in Zeichenfolgen konvertiert werden, unabhängig davon, wie Sie sie festlegen, sodass dieselben Sicherheitsvorkehrungen verfügbar sein sollten. Ich habe noch nie zuvor von einem dauerhaften Wert gehört, der in einem clientseitigen Browserszenario beschädigt wurde. Ich vermute, dass sogar Vanille-Accessoren normalerweise eine Art Schutz haben.
Erik Reppen
Der Punkt über die Namenskollision ist ausgezeichnet. Die lengthEigenschaft wird sich nicht ändern (zumindest in Chrome und Firefox [*]) , wenn Sie anrufen localStorage.setItem("length", something);, aber Sie können abrufen somethingmit localStorage.getItem("length");. Interessanterweise ist das Zuweisen localStorage.length = something;in Chrome ein No-Op, aber in Firefox wird es somethingunter dem Schlüssel gespeichert "length"(den Sie dann nur über die Funktionsoberfläche abrufen können). [*] In Firefox lengthändert sich die Eigenschaft, wenn der Schlüssel "length"noch nicht vorhanden ist localStorage.
Ted Hopp
@ErikReppen - Nach der Spezifikation , localStoragehat sechs vordefinierte Eigenschaften: length, key, getItem, setItem, removeItem, und clear.
Ted Hopp
1

Ich weiß, dass es sich um einen alten Beitrag handelt, aber da niemand die Leistung erwähnt hat, habe ich einige JsPerf-Tests eingerichtet, um sie zu bewerten. Außerdem ist er eine kohärente Benutzeroberfläche getItemund setItemdurchweg schneller als die Verwendung von Punktnotationen oder Klammern und viel einfacher zu lesen.

Hier sind meine Tests auf JsPerf

Dave Mackintosh
quelle
ur jsPerf hat keine Klammern in seinen Test aufgenommen. Ich habe sie hinzugefügt und einige Tests durchgeführt. Die Leistung ist browserbasiert. sowohl auf Chrom als auch auf Firefox getItemund setItemwaren in jeder Kategorie die langsamsten, wobei Punkt auf Chrom am schnellsten und Klammer auf Firefox am schnellsten ist. Ich denke auch, dass "viel einfacher zu lesen" völlig subjektiv ist ... Ja, es gibt die Funktion an, die es ausführt, aber jeder, der jemals mit Objekt- oder Array-Variablen gearbeitet hat, würde in einer halben Sekunde wissen, was mit Punkt / Klammer passiert.
PlantTheIdea
Sie haben Recht, zum Zeitpunkt des Schreibens dieser Tests waren die Getter und Setter durchweg schneller als die Punktnotation. Nicht mehr der Fall. Wenn ich 5 Minuten Zeit habe, komme ich zurück und aktualisiere diese Antwort. Vielen Dank für den Hinweis.
Dave Mackintosh
0

Wie bereits erwähnt, gibt es fast keinen Unterschied außer dem nicht vorhandenen Schlüssel. Der Leistungsunterschied hängt davon ab, welchen Browser / welches Betriebssystem Sie verwenden. Aber so anders ist es nicht.

Ich empfehle Ihnen, die Standardschnittstelle zu verwenden, nur weil dies eine empfohlene Art der Verwendung ist.

Salvador Dali
quelle
"Ich empfehle Ihnen, die Standardschnittstelle zu verwenden" - Beide Schnittstellen sind im Standard angegeben.
Ted Hopp
@ TedHopp Ich denke, dass nur setItem und getItem im Standard angegeben sind .
Salvador Dali
2
Andererseits. Aus dem Standard: "Die unterstützten Eigenschaftsnamen in einem Speicherobjekt sind die Schlüssel jedes Schlüssel / Wert-Paares, das derzeit in der dem Objekt zugeordneten Liste vorhanden ist, in der Reihenfolge, in der die Schlüssel zuletzt zum Speicherbereich hinzugefügt wurden."
Ted Hopp