Chrome 86: TypeError: Accessor properties are not allowed

Viewed 481

I defined a property accessor that used to work before the Chrome Version 86.0.4240.80 (Official Build) (x86_64) update.

const newSetItem = (x, y) => {
    sessionStorage.setItem(`custom_${x}`, y)
}

Object.defineProperty(localStorage, 'setItem', {get: newSetItem, configurable: true, writeable: true})

Also, this is currently working fine in Firefox and Edge and Chrome 85.

Now it throws:

TypeError: Accessor properties are not allowed.

Is this a feature or something is wrong in the latest Chrome version?

1 Answers

You're trying to turn a standard method (setItem) of a host-provided exotic object (localStorage) into a accessor property setter method. Even if it worked, it would be a tremendously bad idea. (Also note that setter methods only accept a single parameter, not two.)

If your goal is make setting something in localStorage set it in sessionStorage instead, the simplest way would be to make the localStorage global point to sessionStorage instead. You can't assign to it (it's read-only), but you can reconfigure it:

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

(Simply let localStorage = sessionStorage; would also work if you could be sure there wasn't any code using window.localStorage.setItem(...) instead of just localStorage.setItem(...) but you probably can't make that assumption.)

I am not recommending doing that, though. I'd do anything I could to change the requirement of writing to localStorage writing to sessionStorage instead. But if you can't, then that's how you'd do it.

If you didn't want to make them equivalent like that, then you'd have to do the same sort of thing to replace localStorage with a Proxy object. The reason it has to be a Proxy is that localStorage and sessionStorage don't only provide access to items through setItem and getItem, they also provide named access as properties (e.g., localStorage.foo = "bar";). The only way to emulate wildcard accessor properties in JavaScript is to use a Proxy object that provides handlers for the the get and set/defineProperty traps.

Related