【问题标题】:Chrome 86: TypeError: Accessor properties are not allowedChrome 86:TypeError:不允许访问器属性
【发布时间】:2020-10-14 11:40:55
【问题描述】:

我定义了一个在 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 的功能还是有问题?

【问题讨论】:

    标签: javascript google-chrome accessor


    【解决方案1】:

    您正在尝试将主机提供的外来对象 (localStorage) 的标准方法 (setItem) 转换为访问器属性设置器方法。即使它奏效了,那也将是一个非常糟糕的主意。 (另请注意,setter 方法只接受一个单个参数,而不是两个。)

    如果您的目标是在localStorage 中设置某些内容,而不是在sessionStorage 中设置,最简单的方法是将localStorage 全局指向sessionStorage。你不能分配给它(它是只读的),但你可以重新配置它:

    Object.defineProperty(window, "localStorage", {
        value: sessionStorage,
        configurable: true
    });
    

    (如果您可以确定没有任何代码使用 window.localStorage.setItem(...) 而不仅仅是 localStorage.setItem(...),那么简单的 let localStorage = sessionStorage; 也可以工作,但您可能无法做出这样的假设。)

    建议这样做。我会尽我所能改变写信给localStorage 的要求,改写给sessionStorage。但如果你不能,那你就是这样做的。

    如果您不想使它们像那样等效,那么您必须做同样的事情来用代理对象替换localStorage。它必须是代理的原因是localStoragesessionStorage 不仅通过setItemgetItem 提供对项目的访问,它们还提供命名访问作为属性(例如,localStorage.foo = "bar";)。在 JavaScript 中模拟通配符访问器属性的唯一方法是使用为 getset/defineProperty 陷阱提供处理程序的代理对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-06
      • 2012-03-11
      • 2012-03-10
      • 2017-02-21
      • 1970-01-01
      • 1970-01-01
      • 2014-05-23
      • 2023-01-04
      相关资源
      最近更新 更多