问题描述
我定义了一个属性访问器,该访问器在Chrome Version 86.0.4240.80 (Official Build) (x86_64)
更新之前就可以使用。
const newSetItem = (x,y) => {
sessionStorage.setItem(`custom_${x}`,y)
}
Object.defineProperty(localStorage,'setItem',{get: newSetItem,configurable: true,writeable: true})
此外,当前在Firefox和Edge和Chrome 85
中也可以正常工作。
现在它抛出:
TypeError: Accessor properties are not allowed.
这是最新的Chrome版本中的功能还是有问题?
解决方法
您正试图将主机提供的奇异对象(setItem
)的标准方法(localStorage
)转换为访问器属性设置器方法。即使可行,这也是一个非常糟糕的主意。 (还请注意,setter方法仅接受一个单个参数,而不是两个。)
如果,您的目标是在localStorage
中设置某项,而在sessionStorage
中设置某项,则最简单的方法是将localStorage
全局指向{ {1}}。您不能分配给它(它是只读的),但是您可以重新配置它:
sessionStorage
(Object.defineProperty(window,"localStorage",{
value: sessionStorage,configurable: true
});
也可以工作,如果您可以确定没有任何代码使用let localStorage = sessionStorage;
而不是window.localStorage.setItem(...)
,但您可能无法做出这样的假设。)
不过,我 不 建议这样做。我将尽一切可能更改将写入localStorage.setItem(...)
的要求改为写入localStorage
的要求。但是,如果做不到,那就是你要做的方式。
如果您不想像这样使它们等效,则必须做同样的事情才能用代理对象替换sessionStorage
。它必须是代理的原因是localStorage
和localStorage
不仅通过sessionStorage
和setItem
提供对项目的访问,它们还提供命名访问作为属性(例如getItem
)。在JavaScript中模拟通配符访问器属性的唯一方法是使用Proxy对象,该对象为localStorage.foo = "bar";
和get
/ set
陷阱提供处理程序。