代码之家  ›  专栏  ›  技术社区  ›  Stephan-v

如何为sessionStorage之类的东西编写适当的ES6包装器

  •  1
  • Stephan-v  · 技术社区  · 7 年前

    sessionStorage .

    我可以通过调用

    class customStorage {
        set(key, value) {
            sessionStorage.setItem(key, value);
        }
    }
    

    我会这样使用它:

    const customStorage = new customStorage();
    customStorage.set('my-key', 'hello there');
    

    会话存储 方法,我可能无法在代理中实现自己。

    比如说 它可以自己编写它们,即使它们可能只需要代理即可 会话存储 没有任何干预。

    用原型覆盖本机功能似乎也是一个致命的陷阱,导致了许多 wtfs-per-minute .

    到目前为止,我从Javascript中的“代理模式”中读到的内容都是从原始对象实现所有方法。我是被迫这样做的吗?

    是否有某种方法可以创建一个ES6类,并将该类的原型设置为构造函数中的sessionStorage之类的?

    1 回复  |  直到 7 年前
        1
  •  2
  •   Bergi    7 年前

    我希望用户可以自由使用其他本机 sessionStorage 方法,我可能无法在代理中实现自己。

    我宁愿给用户只使用本机的自由 会话存储 如果他打算这么做。您的实现确实有自己的独立功能,它使用 会话存储 会话存储 . 没有理由在对象上实现其接口。(另请参见 composition over inheritance ).

    有什么方法可以创建ES6吗 class 会话存储 在构造函数中还是什么?

    SessionStorage 会话存储 是单例,不能实例化第二个 会话存储 ,因此继承在这里绝对不起作用。

    有三种方法可以解决这个问题(我将为通用情况编写代码,从要包装的任意对象实例化,您可能需要一个类似静态单例的自定义存储):

    • function custom(orig) {
          orig.get = function() { … };
          return orig;
      }
      
    • 寄生继承,使用对象上的反射创建完整的包装。

      function custom(orig) {
          const obj = {
              get() { … };
          };
          for (const p in orig) { // assuming everything is enumerable - alternatively use
                                  // for (const p of Object.getOwnPropertyNames(…))
                                  // or even incorporating the prototype chain
              obj[p] = typeof orig[p] == "function"
                ? (...args) => orig[p](...args)
                : orig[p];
          }
          return obj;
      }
      
    • Proxy 用一个 suitable handler :

      const customMethods = {
          get() { … }
      };
      const handler = {
          has(target, name) {
              return name in customMethods || name in target;
          },
          get(target, name) {
              if (name in customMethods) return customMethods[name];
              else return target[name];
              // if its a native object with methods that rely on `this`, you'll need to
              // return target[name].bind(target)
              // for function properties
          }
      }
      
      function custom(orig) {
          return new Proxy(orig, handler);
      }