1

Ich frage mich, wie auf den nativen sessionStorage-Bereich innerhalb meiner benutzerdefinierten Methoden zugreifen.sessionStorage-Proxy-Klassenbereich

Mein Beispiel:

https://jsfiddle.net/3mc7ao7j/1/

In Zeile 3 Ich möchte Proxy in die Lage sein, durch zu meiner Heimat sessionStorage nach meiner Mutation auf den Daten durchzuführen.

Wie kann ich jedoch wieder auf diesen Bereich zugreifen? Ich weiß, ich kann einfach anrufen:

sessionStorage.setItem()

Aber das funktioniert nur, weil es global verfügbar ist und es fühlt sich falsch, das zu tun. Vor allem, weil ich auch wissen möchte, wie ich das ohne ein Objekt, das nicht global verfügbar ist, machen kann, damit ich lernen kann, wie man andere Objekte bevollmächtigt.

Antwort

3

Einige window Objekte wie location sind schreibgeschützt, es kann nützlich sein, Abstraktionen über sie zu erstellen oder DI für die Testbarkeit zu verwenden.

sessionStorage soll verwendet werden wie es ist. Normalerweise werden keine Abstraktionen darüber benötigt. Wenn die Funktionalität erweitert oder geändert werden soll, kann eine benutzerdefinierte Klasse erstellt werden. Es kann Storage Schnittstelle implementieren oder eigene besitzen.

Die Verwendung von Proxy ist hier nicht gerechtfertigt. Es ist langsam und beschränkt die Verwendung des Codes in ES5-Umgebungen.

Benutzerdefinierte Klassen oder Objekte können nur die ursprünglichen sessionStorage Methoden umbrechen. Da Lagerung API klein ist, in den Ergebnissen Wrapper-Klasse ~ 20 Zeilen Code:

class CustomSessionStorage { 
    get length() { 
    return sessionStorage.length; 
    } 

    getItem(key) { 
    return sessionStorage.getItem(key); 
    } 
    ... 
} 

sessionStorage Objekt ist exotisch. Obwohl es von Storage erbt, ist Storage kein Konstruktor, und sessionStorage Methoden sollten direkt an sessionStorage gebunden werden, so dass es nicht möglich ist, es nur mit CustomSessionStorage.prototype = sessionStorage arbeiten zu lassen. Zusätzlich sessionStorage hat length Eigenschaft Beschreibung, die auch gebunden werden sollte.

Eine allgemeinere Art und Weise, sie zu verlängern ist eine Basisklasse zu schaffen, die ursprünglichen Methoden wickelt und kann weiter ausgebaut werden:

function BaseSessionStorage() {} 

for (let prop of Object.getOwnPropertyNames(Storage.prototype)) { 
    if (typeof sessionStorage[prop] === 'function') { 
    // bind all sessionStorage methods 
    BaseSessionStorage.prototype[prop] = sessionStorage[prop].bind(sessionStorage); 
    } else { 
    // a proxy for other props, length is read-only getter 
    Object.defineProperty(BaseSessionStorage.prototype, prop, { 
     get:() => sessionStorage[prop], 
     set: val => { sessionStorage[prop] = val } 
    }); 
    } 
} 

class CustomSessionStorage extends BaseSessionStorage { 
    getItem(key) { 
    return super.getItem(key); 
    } 
    // the rest of API is inherited 
} 
+0

ich einen Proxy benötigen, wenn ich benutzerdefinierte Methoden für eine native Objekt implementieren möchten aber tun Ich möchte nicht alle implementieren. Es geht nicht anders. Wenn ich "JSON.stringify" -Daten immer wenn ich etwas setze und "JSON.parse" erhalte ich bekomme ein Element 90% der Zeit werde ich nicht jedes Mal tun. Ich möchte einfach, dass mein Proxylayer sich darum kümmert. –

+0

Ich sehe keinen wirklichen Bedarf für Proxy hier. Dies kann durch eine reguläre Klasse (oder wahrscheinlich ein Objekt, da ein Speicher ein Singleton sein soll) gehandhabt werden. Bezüglich der ursprünglichen Frage: * Wie greife ich wieder auf diesen Gültigkeitsbereich zu? *, Müssen Sie ihn explizit als 'sessionStorage.setItem()' innerhalb von 'setItem' bezeichnen. Sie können 'this' in Proxy-Methoden verwenden, aber nur, wenn eine Methode anders aufgerufen wird:' set (k, v) {this.setItem (a, msg)} '. – estus

+0

Wenn Sie das Original einfach umbrechen, müssen Sie auch alle Methoden implementieren, wenn es sich wie das native 'sessionStorage'-Objekt verhalten soll. –