Breakpoint on property change Breakpoint on property change javascript javascript

Breakpoint on property change


If you don't mind messing around with the source, you could redefine the property with an accessor.

// original objectvar obj = {    someProp: 10};// save in another propertyobj._someProp = obj.someProp;// overwrite with accessorObject.defineProperty(obj, 'someProp', {    get: function () {        return obj._someProp;    },    set: function (value) {        debugger; // sets breakpoint        obj._someProp = value;    }});


Edit 2016.03: Object.observe is deprecated and removed in Chrome 50

**Edit 2014.05: `Object.observe` was added in Chrome 36**

Chrome 36 ships with native Object.observe implementation that can be leveraged here:

myObj = {a: 1, b: 2};Object.observe(myObj, function (changes){    console.log("Changes:");    console.log(changes);    debugger;})myObj.a = 42;

If you want it only temporarily, you should store callback in a variable and call Object.unobserve when done:

myObj = {a: 1, b: 2};func = function() {debugger;}Object.observe(myObj, func);myObj.a = 42;Object.unobserve(myObj, func);myObj.a = 84;

Note that when using Object.observe, you'll not be notified when the assignment didn't change anything, e.g. if you've written myObj.a = 1.

To see the call stack, you need to enable "async call stack" option in Dev Tools:

chrome async call stack


Original answer (2012.07):

A console.watch sketch as suggested by @katspaugh:

var console = console || {}; // just in caseconsole.watch = function(oObj, sProp) {   var sPrivateProp = "$_"+sProp+"_$"; // to minimize the name clash risk   oObj[sPrivateProp] = oObj[sProp];   // overwrite with accessor   Object.defineProperty(oObj, sProp, {       get: function () {           return oObj[sPrivateProp];       },       set: function (value) {           //console.log("setting " + sProp + " to " + value);            debugger; // sets breakpoint           oObj[sPrivateProp] = value;       }   });}

Invocation:

console.watch(obj, "someProp");

Compatibility:

  • In Chrome 20, you can paste it directly in Dev Tools at runtime!
  • For completeness: in Firebug 1.10 (Firefox 14), you have to inject it in your website (e.g. via Fiddler if you can't edit the source manually); sadly, functions defined from Firebug don't seem to break on debugger (or is it a matter of configuration? please correct me then), but console.log works.
Note that in Firefox, `console.watch` already exists, due to Firefox's non-standard [`Object.watch`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/watch). Hence in Firefox, you can watch for changes natively:
>>> var obj = { foo: 42 }>>> obj.watch('foo', function() { console.log('changed') })>>> obj.foo = 69changed69

Edit: Object.watch was removed in Firefox 57.


There is a library for this: BreakOn()

If you add it to Chrome dev tools as a snippet (sources --> snippets --> right-click --> new --> paste this --> run), you can use it anytime.

enter image description here


To use it, open the dev-tools and run the snippet. Then to break when myObject.myProperty is changed, call this from the dev-console:

breakOn(myObject, 'myProperty');

You could also add the library to your project's debug-build so you don't need to call breakOn again every time you refresh the page.