我想知道如何从我的自定义方法中访问本机 sessionStorage 范围。
我的例子:
https://jsfiddle.net/3mc7ao7j/1/
在第 3 行,我希望能够sessionStorage
在对数据执行突变后代理到我的本地。
我如何再次访问该范围?我知道我可以打电话:
sessionStorage.setItem()
但这很有效,因为它是全球可用的,这样做感觉不对。主要是因为我还想知道如何在没有全局可用的对象的情况下执行此操作,因此我可以学习如何代理其他对象。
我想知道如何从我的自定义方法中访问本机 sessionStorage 范围。
我的例子:
https://jsfiddle.net/3mc7ao7j/1/
在第 3 行,我希望能够sessionStorage
在对数据执行突变后代理到我的本地。
我如何再次访问该范围?我知道我可以打电话:
sessionStorage.setItem()
但这很有效,因为它是全球可用的,这样做感觉不对。主要是因为我还想知道如何在没有全局可用的对象的情况下执行此操作,因此我可以学习如何代理其他对象。
一些window
对象location
是只读的,在它们之上创建抽象或利用 DI 进行可测试性可能很有用。
sessionStorage
应该按原样使用。通常不需要对其进行抽象。如果需要扩展或修改其功能,则可以创建自定义类。它可以实现Storage接口或拥有自己的接口。
这里的使用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
}