我想知道如何从我的自定义方法中访问本机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
}
关于javascript - sessionStorage代理类作用域,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46339476/