sessionStorage代理类作用域 [英] sessionStorage proxy class scope

查看:76
本文介绍了sessionStorage代理类作用域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

我的示例:

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

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

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.

推荐答案

某些窗口对象(如 location )是只读的,在它们上创建抽象可能很有用

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 应该被原样使用。通常,不需要抽象。如果应扩展或修改其功能,则可以创建一个自定义类。它可以实现 Storage 接口或具有自己的接口。

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.

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

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

自定义类或对象只能包装原始的 sessionStorage 方法。由于Storage API很小,包装类产生了约20行代码:

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 对象是奇异的。尽管它是从 Storage 继承的,但是 Storage 不是构造函数,而 sessionStorage 方法应直接绑定到 sessionStorage ,因此无法使其仅与 CustomSessionStorage.prototype = sessionStorage 。此外, sessionStorage 具有 length 属性描述符也应绑定。

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
}

这篇关于sessionStorage代理类作用域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆