50

Similar to other questions here, like this one.

Is there a way to break on the change of a variable value in any JavaScript debugger? (like IE Developer tools, Visual Studio, or Firebug)?

I guess it's something like a "watch variable", but I want to be able to see the callstack and pause it when the change to the variable actually occurs.

An alternative approach might be to override the value setting with a custom setter, and put a breakpoint in that, but unfortunately that won't work for IE AFAIK.

UPDATE It appears that this type of behavior is available at least for unmanaged code written in C++ So I thought maybe a javascript engine written in C++ (Google's V8) might have something similar, but that doesn't appear to have what I want either.

Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
user420667
  • 6,552
  • 15
  • 51
  • 83
  • Simplistic way to totally break the thread is to put an alert in, its annoying yes but you can alert whatever you want, your variable, a string, whatever really. And if your using something like firebug and you have logs in your code then you can step through your program pretty easily with alerts. – Ryan Oct 27 '11 at 04:49
  • 4
    The thing is, I don't know where the variable is changed. It could happen in another file (or one of several). I'm not going to litter my code with alert statements in an attempt to find where it changes. At that point I might as well step through the code line by line with the debugger. Thanks though. – user420667 Oct 27 '11 at 16:15

3 Answers3

16

You don't even need an IDE - you can use "Object.watch()":

Object.Watch Tutorial

If you use any one debugger, I'd strongly recommend Firebug. For all your Javascript, HTML and CSS needs :-):

http://getfirebug.com/javascript

===========================================================

Update for 2019:

  • Object.Watch is Ancient History. Uncoincidentally, it's unavailable in most contemporary browsers.

  • My personal favorite JS debugging tool these days is Chrome Developer Tools.

  • My personal favorite JS IDE (for Angular, .Net Core, etc) is Microsoft Visual Studio Code (MSVC).

  • You can do just about any "expected" debugging operation - including set watches - with the Chrome debugger (just as you could with FF Firebug).

  • Chrome debugger is well integrated with the MSVC IDE.

  • Both are "free" (at least "free as in beer"); both run well on Windows, Mac and Linux.

paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • 4
    +1 b/c I would imagine this would work. However, I don't think it's compatible with a lot of browser atm, b/c it's nonstandard javascript 1.8.6 : https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/watch – user420667 Oct 27 '11 at 16:19
  • Haven't been able to try it out but as the link above specifies using setter/getter methods may be a better approach: https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Working_with_Objects#Defining_getters_and_setters – GuruM Apr 09 '13 at 12:53
  • 5
    2016 not supported in Firefox or Chrome. – Noumenon Apr 02 '16 at 19:45
  • 1
    This [polyfill for `Object.watch`](https://gist.github.com/eligrey/384583) works in ES5-compliant browsers (tested in Chrome 51). – David Harkness Jun 15 '16 at 00:11
  • [`Object.prototype.watch()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/watch) is Firefox-specific. It has been removed in FF 58. Use [getters and setters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Defining_getters_and_setters) and put [`debugger` statement](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger) in them instead. – Palec Apr 24 '18 at 17:37
  • 2018 - Only in FF and has been depricated, so watch() isn't available anymore, and neiter is a solid alternative in the debuggers itself. Back to old alert box littering (sigh) – Minok Jun 19 '18 at 18:31
  • and we are in 2019 and everyone has deprecated it. They should have left it for debug purposes at least. – DanteTheSmith Oct 01 '19 at 23:09
  • In presents days, moderns browsers doesn't provide a `watch` functions (at least on chrome 79.0.3945.79), instead the recommendation is to proxify the object to watch using `defineProperty` func (it let you provide hooks methods that gets called on setting and getting over an object's property) – Victor Dec 13 '19 at 15:32
11

I'm having success with this library in Chrome and it looks to support all major browsers.

https://gist.github.com/eligrey/384583

Just include the .js file, then call:

yourObject.watch('someProperty', function() { 
    doWhatYouWant(); 
    debugger; 
    console.write('this too'); 
    alert('Object Changed'); //etc 
});
rainabba
  • 3,804
  • 35
  • 35
  • Did not work for me using Chrome. I ran the Gist JavaScript first. Then I executed `watch(myObject, 'propertyName', function() { console.log('changed!'); });`. Even though the property value was changing, the console.log message never came. – Joncom Oct 23 '13 at 21:53
  • Check for an error in the console when you call watch(). The library definately works so I'd guess that either it's not loading or your call to it isn't succeeding. – rainabba Oct 24 '13 at 23:16
  • Normally I'd use jsFiddle but they're down right now so here's a working example. Looks like either my syntax was wrong or they've made the approach more smooth (likely the former): http://codepen.io/anon/pen/DAegv – rainabba Oct 24 '13 at 23:35
  • not working for me either, but I'm trying to watch a closure variable... not sure if this supports that or not. not getting errors, but it's never hitting the debugger statement. – Michael Jun 19 '15 at 16:34
0

I don't know if I misunderstood your question. If you want to watch an expression and stop when it reaches a certain value while in a js debugging session in Chrome Developer Tools, it's rather trivial.

You can simply put a breakpoint on the line where the value you want to check is, then click with right mouse button on it and select "Edit breakpoint...". A dialog will pop up prompting for an expression, where execution will stop when its value its true.

For instance, let's say you have a loop and you are adding one unit to a variable inside it and want to stop execution when the variable equals to 3. The expression in loop would look like this:

n = i++;

You must set your breakpoint on that line and the expression to watch (after prompted by "Edit breakpoint...") would be n == 3. When running your code it will stop there when your variable reaches that value.

You'll notice your condition is set because your breakpoint turns orange instead of blue.

Pere
  • 1,068
  • 12
  • 20
  • 1
    If on an adjacent line you had n = i++ (so now you have a loop where i is incremented twice) and you didn't put the breakpoint on the adjacent line, would it stop when n turned 3 on the adjacent line? If not then this wouldn't do what I was looking for. Alternatively if n was a property of an object and it could be set in lots of places, would putting the watch on one setter of n be sufficient to cover all settings of n in all files? – user420667 Sep 24 '15 at 00:24
  • Haven't tried that precise example but to my knowledge I would say yes, as the expression to evaluate in the "Edit breakpoint..." dialog doesn't need to be the same as the code in the line where the breakpoint is placed on. It doesn't need to be a "var equals value" neither; you can put in, for instance, something like `i+j <= k*n`. You can even comment the expression to disable it. It works the same as putting `if(n==3){ dummy = true }` inside your code and placing your breakpoint in the `dummy` line, but just keeping it in the "limbo" of the breakpoint dialogs. Try it yourself to confirm ;) – Pere Sep 24 '15 at 01:00
  • I believe the expression only gets evaluated when the breakpoint is hit. So in the example of two lines of n = i++ with a breakpoint only on one of them, your breakpoint of n == 3 might not get hit depending on which line you put the breakpoint on and your initial value of i. – user420667 Sep 24 '15 at 05:31
  • Sorry my use of "hit" was a little loose in my last comment as I used it to mean two different things. When the breakpoint is hit (by which I'm going to mean the line it's on gets executed and the expression it contains is evaluated), it won't stop unless the expression evaluates to true. However I don't believe that the expression will be evaluated anytime n changes except when the breakpoint is hit. – user420667 Sep 24 '15 at 20:22
  • Very good answer. Thanks for teaching this. For me this is the correct answer. – stravanato Jul 07 '22 at 09:27