Breakpoint on property change Breakpoint on property change google-chrome google-chrome

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.