繁体   English   中英

sessionStorage代理类作用域

[英]sessionStorage proxy class scope

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

我的例子:

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

在第3行,我希望对数据执行更改后能够代理到本机sessionStorage

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

sessionStorage.setItem()

但这只是奏效,因为它在全球范围内都可以使用,并且这样做是错误的。 主要是因为我还想知道在没有全局不可用的对象的情况下如何执行此操作,因此我可以学习如何代理其他对象。

一些window对象(例如location是只读的,在它们之上创建抽象或使用DI进行可测试性很有用。

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

这里不合理使用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
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM