Listen for changes with localStorage on the same window

Since JS is dynamical language just rewrite original functions.

var originalSetItem = localStorage.setItem; 
localStorage.setItem = function(){
    document.createEvent('Event').initEvent('itemInserted', true, true);
    originalSetItem.apply(this, arguments);
}

The answers to this question didn't work for me. I got an Uncaught TypeError: Illegal invocation so I wrote my own code which works in most environments. It uses Proxy which is quite a bit safer.

Storage.prototype.setItem = new Proxy(Storage.prototype.setItem, {
    apply(target, thisArg, argumentList) {
        const event = new CustomEvent('localstorage', {
            detail: {
                key: argumentList[0],
                oldValue: thisArg.getItem(argumentList[0]),
                newValue: argumentList[1],
            },
        });
        window.dispatchEvent(event);
        return Reflect.apply(target, thisArg, argumentList);
    },
});

Storage.prototype.removeItem = new Proxy(Storage.prototype.removeItem, {
    apply(target, thisArg, argumentList) {
        const event = new CustomEvent('localstorage', {
            detail: {
                key: argumentList[0],
            },
        });
        window.dispatchEvent(event);
        return Reflect.apply(target, thisArg, argumentList);
    },
});

Storage.prototype.clear = new Proxy(Storage.prototype.clear, {
    apply(target, thisArg, argumentList) {
        const event = new CustomEvent('localstorage', {
            detail: {
                key: '__all__',
            },
        });
        window.dispatchEvent(event);
        return Reflect.apply(target, thisArg, argumentList);
    },
});

Updated above answer, as document.createEvent now is part of an old, deprecated API.

const originalSetItem = localStorage.setItem;

localStorage.setItem = function(key, value) {
  const event = new Event('itemInserted');

  event.value = value; // Optional..
  event.key = key; // Optional..

  document.dispatchEvent(event);

  originalSetItem.apply(this, arguments);
};

const localStorageSetHandler = function(e) {
  alert('localStorage.set("' + e.key + '", "' + e.value + '") was called');
};

document.addEventListener("itemInserted", localStorageSetHandler, false);

localStorage.setItem('foo', 'bar'); // Pops an alert

https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events