sessionStorage代理类范围

时间:2017-09-21 08:52:59

标签: javascript ecmascript-6 es6-class sessionstorage es6-proxy

我想知道如何从我的自定义方法中访问本机sessionStorage范围。

我的例子:

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

在第3行,我希望能够在对数据执行变异后代理到我的原生sessionStorage

我如何再次访问该范围?我知道我可以打电话:

sessionStorage.setItem()

但这很有效,因为它是全球可用的,这样做感觉不对。主要是因为我还想知道如何在没有全局可用的对象的情况下执行此操作,以便我可以学习如何代理其他对象。

1 个答案:

答案 0 :(得分:4)

window之类的一些location对象是只读的,它们可以用于创建抽象或使用DI进行可测试性。

sessionStorage应该按原样使用。通常不需要抽象。如果应扩展或修改其功能,则可以创建自定义类。它可以实现Storage接口或拥有自己的接口。

Proxy的使用在这里是没有道理的。它很慢并且限制了代码在ES5环境中的使用。

自定义类或对象可以只包装原始sessionStorage方法。由于Storage 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
}