Tracking down where a property changes in JavaScript


Without strict enforcement of boundaries, it can be a mystery where changes happen in the state in your JavaScript application (this is a reason tools like Redux are compelling). I was recently investigating a bug in an app where the source of a state change was a mystery. The app keeps track of the count of videos uploaded. Deleting a video could sometimes cause the count to decrement twice when it should only decrement once. I would be able to find this bug quickly if I could get a stack trace every time the state was modified.

This isn't a new problem. You may remember the promise of and Object.observe() before they were deprecated.

Let's talk about some current options.


Proxy allows you to create a replacement for your object that wraps the original object. You can define your own set "trap" to log the stack trace (or break into a debugger, etc.).


let proxy = new Proxy(objectYouWantToObserve, {
  set: function(obj, prop, value) {
    if (prop === 'thePropertyWeWantToObserve') {
      console.trace(`set: ${prop} -> ${value}`)

    // The default behavior to store the value
    obj[prop] = value;

    // Indicate success
    return true;

  // you can optionally define an additional trap for `get` if you're also
  // interested in tracking reads for the property

You would then need to use your proxy instance wherever you would have used objectYouWantToObserve.

The downside of this approach is that, depending on your app design, it isn't always convenient to replace references to the original object.


Paul Irish's library break-on-access exposes a breakOn function that will happily invoke the debugger whenever a property is modified (or, optionally, accessed for read).


breakOn(objectYouWantToObserve, "thePropertyWeWantToObserve")

The upside of this approach is that it requires no additional modification to your code. Any changes to thePropertyWeWantToObserve will invoke the debugger.

I keep break-on-access in my Chrome snippets and reach for it first when I need to track down a change in and object's top-level property.

What if I need to observe changes in dynamically nested objects?

If you need to observe properties changing in nested objects, break-on-access won't help you. With some effort, you can use nested Proxys by returning a new Proxy from the Proxy's set trap. I'd also consider something like Observable Slim since it allows observing even deeply-nested changes to an object and its usage is similar to that of Proxy.

My goofy face

Hi, I'm Jeffrey Chupp.
I solve problems, often with code.