JavaScript/Objekte/Storage

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Das Storage-Objekt ist ein Teil des WebStorage-API. Storage-Objekte werden vom Browser erzeugt, um den Inhalt des Local Storage und des Session Storage aufzunehmen.

Weiter führende Informationen zum WebStorage API und Beispiele finden Sie im WebStorage-API Artikel.

Vererbungshierarchie

Storage-Objekt
Storage.prototype

Storage

Es gibt zwar ein globales Objekt Storage, das formal die Konstruktorfunktion für Storage-Objekte darstellt, diese Funktion kann aber weder direkt noch über den new-Operator aufgerufen werden. Sie besitzt auch keine eigenen Eigenschaften oder Methoden. Ihr einziger Zweck ist es, in Storage.prototype das Prototyp-Objekt für Storage-Objekte bereitzustellen.

Storage.prototype

Eigenschaften

  • length

Achtung!

Die Argumente für getItem, setItem und removeItem sind vom Typ String. Wenn Sie einen Wert mit einem anderen Datentyp übergeben, wird er in einen String konvertiert. Dies kann unerwartete Konsequenzen haben:
  • Die Werte undefined und null werden in 'undefined' und 'null' konvertiert
  • Objekte werden mittels ihrer toString() konvertiert. Die wenigsten Objekte implementieren hier eine Konvertierung, die zu einem String führt, aus dem sich das Objekt später rekonstruieren lässt.
Empfehlung: Verwenden Sie zum Speichern von Objekten in einem Storage-Objekt JSON.stringify(), um eine Zeichenkette zu erhalten, aus der Sie das Objekt später mittels JSON.parse() wiederherstellen können.

length

Die length Eigenschaft wird, anders als beispielsweise bei Arrays, von Storage.prototype an Storage-Objekte vererbt. Sie ermittelt die Anzahl der im Storage-Objekt gespeicherten Schlüssel

getItem(key)

Die getItem-Methode liest den Wert aus, der unter den angegebenen Schlüssel abgelegt wurde. Wenn Sie als Schlüssel etwas anderes als eine Zeichenkette übergeben, wird es in einen String konvertiert.

Parameter Typ Bedeutung
key Zeichenkette Name eines im Storage abgelegten Name-Wert (key-value) Paares
Rückgabewert Zeichenkette Der Wert, der unter dem angegebenen Namen gespeichert ist, oder null, wenn unter diesem Schlüssel nichts gespeichert war.

setItem(key, value)

Mit setItem() speichern Sie im Storage-Objekt einen Wert.

Beachten Sie: Wenn ein Eintrag mit diesem key schon besteht, wird er ohne Warnung überschrieben.
Parameter Typ Bedeutung
key Zeichenkette Name, unter dem der Inhalt des value-Parameters im Storage abgelegt werden soll
value Zeichenkette Der zu speichernde Wert.
Rückgabewert undefined

removeItem(key)

removeItem löscht einen Eintrag aus dem Storage-Objekt.

Parameter Typ Bedeutung
key Zeichenkette Name des Schlüssels, der mit seinem Wert zu entfernen ist
Rückgabewert undefined

key(index)

Parameter Typ Bedeutung
index Integer Nummer von 0 bis (length-1)
Rückgabewert Der unter der übergebenen Nummer gespeicherte Schlüsselname

Sie können die key()-Methode verwenden, um alle Schlüsselnamen in einem Storage-Objekt zu ermitteln. Durchlaufen Sie dafür in einer Schleife die Werte von 0 bis (length-1) und rufen Sie key() mit diesen Indexnummern auf. Die Reihenfolge der Schlüssel ist nicht festgelegt - wenn Sie die Schlüssel alphabetisch haben möchten, müssen Sie sie sortieren. Die Zugangsreihenfolge der Schlüssel (wie zum Beispiel in einem assoziativen PHP Array) wird vom Storage-Objekt nicht festgehalten.

clear()

Die Methode clear() erwartet keinen Parameter und gibt auch nichts zurück. Sie löscht den Inhalt des Storage-Objekts vollständig.

Beispiele

Speichern und Lesen von Strings

Das Speichern von Zeichenketten funktioniert sehr einfach:

Beispiel
localStorage.setItem('Aufgabe_1', 'Aktiv am Self-Wiki mitarbeiten!');
console.log('Aufgabe 1: ' + localStorage.getItem('Aufgabe_1'));

Zahlen, Boolesche Werte, Date-Objekte

Sie können an setItem() als Wert auch Zahlen, boolesche Werte oder Datumsobjekte übergeben. Diese werden in einen String konvertiert und gespeichert. Um sie nach dem Auslesen mit getItem() wieder in ihren ursprünglichen Typ zurückzuwandeln, müssen Sie ihn konvertieren. Angenommen, dass der gelesene Wert in der Variablen wert steht, können Sie

Integer-Werte mit Number(wert) oder parseInt(wert) konvertieren
Fließkomma-Werte mit Number(wert) oder parseFloat(wert) konvertieren
Date-Werte mit new Date(wert) konvertieren
Sie müssen new verwenden, weil ein Date ein Objekt ist.
Boolean-Werte mit (wert === 'true') konvertieren
Beispiel
localStorage.setItem("zahl", 47.11);
localStorage.setItem("logik", false);
localStorage.setItem("datum", new Date(2023,03,14));   // Monat 3 ist April!

const zahl = Number(localStorage.getItem("zahl"));
const logik = Boolean(localStorage.getItem("logik"));
const heute = new Date(localStorage.getItem("datum"));   // Achtung, hier new verwenden!

Symbole

Symbole lassen sich nicht in einem Storage-Objekt speichern. Weder direkt, noch als Wert einer Objekteigenschaft (JSON.stringify überspringt Eigenschaften, in denen ein Symbol gespeichert ist).

Probleme mit undefined und null

Achten Sie darauf, dass Sie nicht null oder undefined als key oder value an eine der Storage-Methoden übergeben. Die automatische Umwandlung in Zeichenketten findet auch hier statt, und zwar rücksichtslos in die Zeichenketten "null" beziehungsweise "undefined".

Probleme mit null
const storageKey = null;
localStorage.setItem(storageKey, 'Dreimol Null es Null es Null...');

console.log("Unter dem Schlüssel 'null' finden Sie: " + localStorage.getItem('null'));
// Schöne Jröß uss d'r Kayjass

Arrays und beliebige Objekte

Wenn Sie ein Array oder ein Objekt (außer Date) speichern möchten, dann sollten Sie das mit Hilfe einer JSON-Codierung tun.

Beispiel
const info = {
   thema: 'Web Storage API',
   abschnitt: 'Speichern von Werten'
   text: 'Verwenden Sie die <code>setItem</code>-Methode zum Speichern.'
};
localStorage.setItem('aktueller_abschnitt', JSON.stringify(info));

let storedInfo = JSON.parse(localStorage.getItem('aktueller_abschnitt'));
console.log('Aktueller Abschnitt: ' + storedInfo.abschnitt);
console.log(storedInfo.text);

Vorhandene Schlüssel im localStorage

Das Storage-Objekt besitzt eine length-Eigenschaft, die die Anzahl der darin abgelegten Einträge zurückliefert. Damit können Sie eine Schleife programmieren, um mit Hilfe der Methode key(n) den an Position n gespeicherten Schlüssel zu bestimmen und darüber dann den gespeicherten Wert zu erhalten. Die Schlüsselnummern laufen von 0 bis length - 1.

Abrufen aller Einträge im Local Storage
for (let i=0; i < localStorage.length; i++) { 
  let storageKey = localStorage.key(i);
  console.log(storageKey + ' : ' + localStorage.getItem(storageKey));
}
Hinweis:
Wenn Sie key() mit einer ungültigen Schlüsselnummer aufrufen, erhalten Sie keinen Fehler, sondern den JavaScript-Wert null (der für "kein Objekt vorhanden" steht). Das gleiche geschieht, wenn Sie getItem() mit einem unbekannten Schlüsselnamen aufrufen.

Alternativer Zugriff mit Eigenschaften

Achtung!

Hier handelt es sich um ein „Bequemlichkeits-Feature“, bei dem es gefährliche Randbedingungen gibt. Verwenden Sie es nicht, verwenden Sie immer die Methoden getItem(), setItem() und removeItem().

Da Sie die Eigenschaften-Schreibweise bei fremdem Code vorfinden können, wollen wir sie dennoch beschreiben.

Die setItem() Methode speichert das übergebene Name-Wert Paar in einer internen Datenstruktur des Storage-Objekts. Gleichzeitig erzeugt sie aber auch auf dem Storage-Objekt eine neue Eigenschaft, deren Name dem übergebenen Namen entspricht. Es sei denn, dieser Name wird bereits von einer Eigenschaft oder Methode verwendet, die das Storage-Objekt erbt.

Der Aufruf

   localStorage.setItem('selfhtml', 'Die Energie des Verstehens');

erzeugt auf dem Storage-Objekt eine Eigenschaft namens selfhtml, auf die Sie mit

   localStorage.selfhtml

zugreifen können. Sie können diese Eigenschaft auch mittels

   localStorage.selfhtml = 'Die Energie des Verstehens';

erzeugen, das Storage-Objekt erkennt den Schreibzugriff auf eine Eigenschaft und überträgt das in seine interne Datenstruktur.

Wenn Sie einen Schlüsselnamen verwenden, der als JavaScript-Name nicht zulässig ist, können Sie - wie bei normalen Objekten - auch auf die Indexschreibweise zurückgreifen:

   localStorage['Key.47-11'] = 'Echt Kölnisch Wasser';

Praktisch? Vielleicht.

Robuster Code? NEIN!

Denn diese Synchronisierung zwischen Storage und Objekteigenschaften funktioniert nicht immer. Wenn Sie als Storage-Schlüssel einen Namen verwenden, der sich in Storage.prototype oder Object.prototype befindet, dann schreibt setItem den Wert nur in den Storage-Speicher. Eine Objekteigenschaft wird hingegen nicht erzeugt. Verwenden Sie hingegen die Eigenschaften-Syntax, ist es genau andersherum: Eine Objekteigenschaft wird erzeugt und die geerbte Eigenschaft überdeckt, ein Storage-Eintrag entsteht hingegen nicht.

Die folgende Tabelle soll das verdeutlichen. Beim Eigenschaftenzugriff sind die Punkt-Syntax und die Index-Syntax gleichwertig, darum zeigen wir hier nur eine davon.

Sie verwenden Storage-
Eintrag
Objekt-
Eigenschaft
localStorage.selfhtml = 'Energie' entsteht entsteht
localStorage.setItem('selfhtml', 'Energie') entsteht entsteht
localStorage.clear = 'Energie' NEIN! entsteht
localStorage.setItem('clear', 'Energie') entsteht NEIN!

Dieses Verhalten hat zwei gemeingefährliche Eigenschaften:

  • Wenn Sie eine direkte Eigenschaftenzuweisung machen und dabei versehentlich einen vererbten Namen erwischen, dann töten Sie für diesen Namen die Vererbung. Nach localStorage[key] = '42' können Sie, wenn in key zufällig 'getItem' stand, keine Storage-Einträge mehr mit localStorage.getItem() abrufen.
  • Wenn Sie andersherum mit localStorage.setItem(key, '42') schreiben und mit localStorage[key] abrufen wollen, dann erhalten Sie nicht '42', sondern das Funktionsobjekt, wenn in key zufällig der Name einer geerbten Methode wie clear stand

Achtung!

Folgen Sie unserer Empfehlung und vermeiden Sie die Eigenschaften-Schreibweise

Links