
Many people ask me the same question:
“How to debug this $% *!% $! Javascript?
So, first of all, JavaScript is not $% *!% $! And as I debug him - I'll tell you now.
')
(
Note : probably this article is more for beginners. So do not judge strictly)
It would seem - what is there to tell? Still obvious. But this question is asked to me with an enviable frequency. Yes, and I have something to tell.
I will give specific examples and tell you how I solve them.
We see the goal, we do not see obstacles
Javascript dumped error? Wonderful! No, this is of course bad, but much better than if he were silent (yes, sometimes it happens!) In case of an error.
Our goal is to understand what the hell happened? But first, a
commercial break is a lyrical digression: JavaScript Debug tools in major browsers.
Debuggers
Here are the main browsers and their debugging tools:
In all these debugging tools, we will be interested in breakpoints:

And here are some “goodies” - conditional breakpoints (right click on the “breakpoint”):

That is, we start a global variable (for example)
allowBreakpoints
and “bryaks” will work only when we ourselves want it.
Unfortunately, it does not work everywhere, so I usually do not use it.
How to "slow down" the flow
Debugger keyword Upon seeing this in the code, any self-respecting JS-debugger will stop the flow of JavaScript and show us where it stopped

You can safely use it in:
Firefox with Firebug enabled
Safari
Chrome with open / enabled Web Inspector / Script Panel
Internet Explorer 8 with Developer Tools open / enabled
Internet Explorer <= 7 with Script Debugger installed
Opera with open / on dragonfly
And do not be afraid to write a
debugger
in your code - errors will not cause it anywhere.
But the option with the conditional stop:
if (allowBreakpoints == true )
debugger;
* This source code was highlighted with Source Code Highlighter .
I like it so much more than putting a “crack”: this is how I write the code and basically debug it in one place, not two.
Debug via alert ()
This is the least informative debug, which also stops the flow of JavaScript. And besides, modal to the browser. Forget that it exists at all.
Breakpoint feature
These options all, as one, inhibit the flow of JavaScript. This is
bad!Why? If at the time the script was stopped, you had an AJAX request or a Timeout running, and the answer did not return, it may never return. Agree, in modern web-projects of this good enough. Therefore, at the time of the “emergency stop” of the script, we can no longer adequately debug further - a part of the logic will be irretrievably lost.
Therefore, I try to avoid in practice debug with a stop.
“Debugging JavaScript with breakpoints is bad, mmkay?” © Mr. Mackey, South Park
However: breakpoint is a breakpoint, and if you investigate a well-launched bug, you can’t do without a stop here (you’ll have to make watch the current variable, etc.)
“Right” debug
In short: good debug - through logging. So I basically work - in the right place at the right time
console.log(...)
works
console.log(...)
.
Yes, about
console.log
- for the first time this method saw the world, as far as I remember, along with Firebug. No this is not the standard and not the fact that it will work in IE6. However, modern browsers log in exactly like
console.log
. This is so note. And if the production gets code from
console.log(...)
- be on the alert, it can break! So it may be worth redefining the
console
object in your code, just for every fireman.
If there is no
console.log
in the target browser, but I want to - try
Firebug Lite or
Blackbird , maybe you will like it;)
Example №1
JavaScript showed an error. We need to understand - what's what.
We turn on the “Break On Error” mode in the debugger:

Reproduce the error again. Javascript stops. We see the place of the error, we make a watch and we precisely determine what the matter is.
Example 2
CASE:Javascript showed no error. But you know what it is (like a gopher). Yes, it happens sometimes.
CASE:You just need to pass some code. Let's say, to see what happens at the touch of a button or after AJAX-loading data.
It's harder here - you need to find where to start.
Little art
Finding the JavaScript entry point is not an easy thing. Here is how I do it:
- The most important thing is to understand the development tool . Whether it is jQuery, or ExtJS, or Mootools, or even your own framework - you need to understand how a button is created, how an event handler is “hung”, how data goes to AJAX, how to get into the grid, how TinyMCE RTE works, how, how ... If there is no understanding of the problem - it will not work to solve it!
- Use Inspect of our debugger (if there is no Inspect, use Firebug Lite ):
- Find the HTML element you need (for example, a button)
- We are looking for the nearest element with a meaningful ID (eg: id = "my-super-button"; and id = "ext-gen124" is no longer appropriate) up the hierarchy (it could be the button itself, or maybe DIV four levels above)
- We are looking for in our code the entry of this meaningful ID's
- Found Ok, now we thoughtfully read the code and find the right place (button click handler, AJAX request, etc.)
- We write in the right place
debugger
://
if (allowBreakpoints == true )
debugger;
//
debugger;
* This source code was highlighted with Source Code Highlighter .
Of course, this method is not perfect. It happens that gives miss. But this is a good way, he strongly helps me in my work.
So, it means that they found a place in the code, set it up. If you don’t want to (or simply don’t) change the source code, you can put a brakepoint in the debugging tool instead of the
debugger
keyword.
Example 3
The same case: you need to punch some code. Let's say, to see what happens at the touch of a button or after AJAX-loading data. But this time we can not slow down the flow of JavaScript for the reasons I described.
So:
- We are looking for the right place in the same way.
- Instead of
debugger
we write console.log(variable_to_watch)
There are interesting upgrades.
CASE UNO
variable_to_watch
- an object that has changed since it was output to the console. And I want to see his condition at the time of the call.
Here you need to use not
console.log(variable_to_watch)
, but
console.dir (variable_to_watch)
CASE DUO
You need to not only see the current value of the
variable_to_watch
, but also experiment with it (for example, you want to call its method):
// obj
if (debugEnabled)
console.log(window.temp_var = obj);
* This source code was highlighted with Source Code Highlighter .
Thus, we will not only see the output in the console, but also get access to the object through a global link to it:
window.temp_var
.
Open Firebug-> Console and call the method:
temp_var.objMethod()
.
No console? We write in the address bar:
javascript:alert(temp_var.objMethod()); void 0;
javascript:alert(temp_var.objMethod()); void 0;
Example 4
One more example. Perhaps a little weird. I would like to punch through the 3d-party-framework method (for example, ExtJS), but the trouble is that you cannot slow down JavaScript and there is no access to the source code (a strange example though? :)
What to do? I do this:
Create a file with the patch:
my-ext-patch.js , and connect it
after ext-all.jsInside we write something like:
( function () {
var _backup = Ext.form.Form.render; // . -- ;)
Ext.form.Form.render = function (container) { // Wrap'
//
console.log(container);
// :
// console.dir(container);
// console.log(window.t = container);
// debugger;
//
return _backup.apply( this , arguments);
}
})();
* This source code was highlighted with Source Code Highlighter .
Perversion? Maybe. But I like> :)
Epilogue
This is how you can debug
"this $% *!% $!" JavaScript. It is important to focus on the first three examples.
I hope that my experience will help someone.