7

I am trying to override the dot notation for access to localStorage. I already managed to override the getItem and setItem methods as described here: Is it possible to override Local Storage and Session Storage separately in HTML5?

Now I tried to create a Proxy to also catch the dot access, but since I seem to be unable to overwrite the localStorage object as tried here

localStorage  = new Proxy(localStorage, {
get: function(target, name) {
    if (!(name in target)) {
        console.log("Getting non-existent property '" + name + "'");
        return undefined;
    }
    return '123';
},
set: function(target, name, value) {
    if (!(name in target)) {
        console.log("Setting non-existent property '" + name + "', initial value: " + value);
    }
    target[name] = value;
}
});

Now when I try it I still get test instead of 123:

localStorage.testKey = "test";
alert(localStorage.testKey)
Community
  • 1
  • 1
Display name
  • 2,697
  • 2
  • 31
  • 49
  • Proxy object cannot have the same name as the object it virtualizes. Actually your `get` / `set` methods haven't been called. Try add `console.log` call in each method (outside `if`) and you'll see. – hindmost Nov 24 '15 at 08:59
  • I know that my methods are not getting called, question is whether there is any way to get them called – Display name Nov 24 '15 at 12:33
  • _whether there is any way to get them called._ Use different name/identifier for proxy object (everything but `localStorage`). – hindmost Nov 24 '15 at 13:30

2 Answers2

1

If you define the getter on localStorage it should work:

Object.defineProperty(window, "localStorage", new (function () {
    this.get = function() {
      console.log("I'm getting called");
    }
})());
Elvio Cavalcante
  • 476
  • 5
  • 10
1

window.localStorage is a read-only property, so you cannot just reassign it like that.

(I recommend turning on strict mode, which would have alerted you to this fact by throwing an exception.)

However, it is configurable. If you delete it from the window object first, your code will work as intended.

var lsProxy = new Proxy(localStorage, {
    /* insert descriptor here */
});

delete window.localStorage;
window.localStorage = lsProxy;

You could also redefine it with Object.defineProperty.

Object.defineProperty(window, "localStorage", {
    value: lsProxy,
    configurable: true,
    enumerable: true,
    writable: false
}); 
a cat
  • 654
  • 1
  • 10
  • 17