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
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:
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), butconsole.log
works.
>>> 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.
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.