Object.watch() for all browsers?

(Sorry for the cross-posting, but this answer I gave to a similar question works fine here)

I have created a small object.watch shim for this a while ago. It works in IE8, Safari, Chrome, Firefox, Opera, etc.


That plugin simply uses a timer/interval to repeatedly check for changes on an object. Maybe good enough but personally I would like more immediacy as an observer.

Here's an attempt at bringing watch/unwatch to IE: http://webreflection.blogspot.com/2009/01/internet-explorer-object-watch.html.

It does change the syntax from the Firefox way of adding observers. Instead of :

var obj = {foo:'bar'};
obj.watch('foo', fooChanged);

You do:

var obj = {foo:'bar'};
var watcher = createWatcher(obj);
watcher.watch('foo', fooChanged);

Not as sweet, but as an observer you are notified immediately.


The answers to this question are a bit outdated. Object.watch and Object.observe are both deprecated and should not be used.

Today, you can now use the Proxy object to monitor (and intercept) changes made to an object. Here's a basic example:

var targetObj = {};
var targetProxy = new Proxy(targetObj, {
  set: function (target, key, value) {
      console.log(`${key} set to ${value}`);
      target[key] = value;
  }
});

targetProxy.hello_world = "test"; // console: 'hello_world set to test'

If you need to observe changes made to a nested object, then you need to use a specialized library. I published Observable Slim and it works like this:

var test = {testing:{}};
var p = ObservableSlim.create(test, true, function(changes) {
    console.log(JSON.stringify(changes));
});

p.testing.blah = 42; // console:  [{"type":"add","target":{"blah":42},"property":"blah","newValue":42,"currentPath":"testing.blah",jsonPointer:"/testing/blah","proxy":{"blah":42}}]