简体   繁体   English

sessionStorage代理类作用域

[英]sessionStorage proxy class scope

I am wondering how to access the native sessionStorage scope from within my custom methods. 我想知道如何从我的自定义方法中访问本机sessionStorage范围。

My example: 我的例子:

https://jsfiddle.net/3mc7ao7j/1/ 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. 在第3行,我希望对数据执行更改后能够代理到本机sessionStorage

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. 主要是因为我还想知道在没有全局不可用的对象的情况下如何执行此操作,因此我可以学习如何代理其他对象。

Some window objects like location are read-only, it can be useful to create abstractions over them or make use of DI for testability. 一些window对象(例如location是只读的,在它们之上创建抽象或使用DI进行可测试性很有用。

sessionStorage is supposed to be used as is. sessionStorage应该按原样使用。 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. 这里不合理使用Proxy It is slow and restricts the code from being used in ES5 environments. 它很慢,并且限制了代码在ES5环境中的使用。

Custom class or object can just wrap original sessionStorage methods. 自定义类或对象只能包装原始的sessionStorage方法。 Since Storage API is small, wrapper class results in ~20 lines of code: 由于Storage API很小,包装器类导致大约20行代码:

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

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

sessionStorage object is exotic. sessionStorage对象是奇异的。 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 . 尽管它是从Storage继承的,但是Storage并不是构造函数,并且sessionStorage方法应该直接绑定到sessionStorage ,因此不可能仅通过CustomSessionStorage.prototype = sessionStorage使其工作。 Additionally, sessionStorage has length property descriptor that should be bound as well. 另外, sessionStorage具有应该绑定的length属性描述符。

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
}

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

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