2017-09-21 11 views
1

私のカスタムメソッド内からネイティブのsessionStorageスコープにアクセスする方法が不思議です。sessionStorageプロキシクラスのスコープ

私の例:3行目で

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

私はデータに私の突然変異を実行した後、私の母国sessionStorageに至るまでのプロキシのことができるようにしたいと思います。

どうすればそのスコープに再度アクセスできますか?

sessionStorage.setItem()

しかし、それは世界的に利用可能であり、それはそれを行うには間違った感じているので、単純に動作することを:私はちょうど呼び出すことができます知っています。主に、グローバルには利用できないオブジェクトなしでこれを行う方法も知りたいので、他のオブジェクトを代理する方法を学ぶことができます。

答えて

3

locationのようなオブジェクトの一部は読み取り専用です。抽象的なオブジェクトを作成したり、テスト容易性のためにDIを使用すると便利です。

sessionStorageをそのまま用いるものとする。通常、それ以上の抽象化は必要ありません。その機能を拡張または変更する必要がある場合は、カスタムクラスを作成できます。それはStorageインターフェイスを実装するか、独自のインターフェイスを持つことができます。

Proxyの使用はここでは正当ではありません。それは遅く、コードがES5環境で使用されることを制限します。

カスタムクラスまたはオブジェクトは、元のsessionStorageメソッドをラップするだけです。ストレージAPIは小さいので、コードの〜20行でラッパークラスの結果:

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

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

sessionStorageは、オブジェクトがエキゾチックです。 Storageから継承していますが、Storageはコンストラクタではなく、sessionStorageメソッドはsessionStorageに直接バインドする必要があります。したがって、CustomSessionStorage.prototype = sessionStorageと一緒に動作させることはできません。さらに、sessionStorageは、バインドされるべきであるlengthのプロパティ記述子を持っています。

それを拡張するために、より一般的な方法は、元のメソッドをラップの基本クラスを提供することで、さらに拡張することができます。

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

を私はネイティブオブジェクトのカスタムメソッドを実装する場合、プロキシを必要とするが、やりますそれらのすべてを実装する必要はありません。他の方法はありません。私が何かを設定し、 'JSON.parse'を設定するたびにデータを' JSON.stringify 'したいのであれば、毎回これをやっていない時間の90%を取得します。私は単に私のproxylayerがこの世話をしたい。 –

+0

私はここにプロキシの本当の必要性を見ません。これは、通常のクラス(またはストレージはシングルトンであるはずなのでオブジェクト)によって処理できます。元の質問については、どうしたら?*を使って再びそのスコープにアクセスするには、 'setItem'の中で' sessionStorage.setItem() 'と明示的に参照する必要があります。 'set(k、v){this.setItem(a、msg)}'。プロキシメソッドで 'this'を使うことができます。 – estus

+0

元の 'sessionStorage'オブジェクトのように振る舞うようにするには、オリジナルを単にラップするだけですべてのメソッドを実装する必要があります。 –

関連する問題