1

您好,我想知道如何为类似sessionStorage.

我可以通过对sessionStorage. 例如一些快速的伪代码:

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

我会这样使用它:

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

一切都很好,但我希望用户可以自由地在我的代理上使用其他本机sessionStorage方法,我可能不会在我的代理中实现自己。

因为sessionStorage即使他们可能做的只是在sessionStorage没有任何干预的情况下代理,也可以自己编写所有类似的东西。

对于更大的东西,我只会操纵 20 种方法中的 5 种方法,或者这似乎不可行。

用原型覆盖本机功能似乎也是导致许多wtfs-per-minute.

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

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

4

1 回答 1

2

我希望用户可以自由地sessionStorage在我的代理上使用我可能不会在我的代理中实现自己的其他本机方法。

如果他打算这样做,我宁愿给用户sessionStorage 直接使用本机的自由。您的实现确实有自己的独立功能,它在sessionStorage内部使用但不是sessionStorage. 没有理由在您的对象上实现其接口。(另见组合优于继承)。

是否有某种方法可以创建 ES6class并将该类的原型设置为sessionStorage构造函数或其他东西?

不。即使您想实现该接口,您的对象也不是真正的SessionStorage实例。同样在这种特殊情况下,sessionStorage是一个单例,你不能实例化第二个SessionStorage,所以继承在这里绝对不起作用。

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

  • Mixins 来装饰对象。不要创建另一个实例,只需覆盖原始实例的属性。(对于内置对象,这可能是不可能的)

    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带有合适处理程序的文字:

    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);
    }
    
于 2017-09-20T14:53:28.940 回答