Chrome 86:TypeError:不允许访问器属性

问题描述

我定义了一个属性访问器,该访问器在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。它必须是代理的原因是localStoragelocalStorage不仅通过sessionStoragesetItem提供对项目的访问,它们还提供命名访问作为属性(例如getItem)。在JavaScript中模拟通配符访问器属性的唯一方法是使用Proxy对象,该对象为localStorage.foo = "bar";get / set陷阱提供处理程序。