sessionStorage proxy class scope

喜夏-厌秋 提交于 2019-12-13 01:07:06

问题


I am wondering how to access the native sessionStorage scope from within my custom methods.

My example:

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

At line 3 I would like to be able to proxy through to my native sessionStorage after perform my mutation on the data.

How do I access that scope again though? I know I can just call:

sessionStorage.setItem()

But that simply works because it is globally available and it feels wrong to do that. Mainly because I would also want to know how to do this without an object that is not globally available so I can learn how to proxy other objects.


回答1:


Some window objects like location are read-only, it can be useful to create abstractions over them or make use of DI for testability.

sessionStorage is supposed to be used as is. Usually no abstractions over it are needed. If its functionality should be extended or modified, a custom class can be created. It can implement Storage interface or have its own.

The use of Proxy is unjustified here. It is slow and restricts the code from being used in ES5 environments.

Custom class or object can just wrap original sessionStorage methods. Since Storage API is small, wrapper class results in ~20 lines of code:

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

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

sessionStorage object is exotic. Although it inherits from Storage, Storage is not a constructor, and sessionStorage methods should be bound to sessionStorage directly, so it's not possible to make it work just with CustomSessionStorage.prototype = sessionStorage. Additionally, sessionStorage has length property descriptor that should be bound as well.

A more general way to extend it is to provide a base class that wraps original methods and can be extended further:

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
}


来源:https://stackoverflow.com/questions/46339476/sessionstorage-proxy-class-scope

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!