Demo: Demo: Debugging JavaScript in the Browser

Using your developer tools to debug live JavaScript code as it executes.

Scroll down...

Content

Resources

Comments

Like with any language, working with JavaScript you quickly arrive at a point where you want to debug your code. JavaScript was born in the browser. When writing client-side applications, that is exactly where you're going to want to fine-tune your programs.

Although you should test your code in all major browsers, much of the functionality is browser agnostic. When you want to debug the core logic and features of your JavaScript you turn to your browser's developer tools. Google Chrome's Developer Tools come enabled with powerful features for debugging and profiling JavaScript.

Some browsers require you to enable the developer tools, but most will allow you to open them with cmd + option + I.

Example Code

If you'd like to try out some of the examples the code is available at this Github repo.

Chrome Developer Tools

You will most likely want to start up a local server to run the examples. Use $ ruby -run -e httpd . -p 3000 to start up a local WEBrick server. Then navigate to http://localhost:3000 in your browser.

You should see something like this:

JS Chrome Developer Tools Demo Homepage

You can open up the Chrome developer tools with cmd + option + I or in the View > Developer > Developer Tools menu.

Open Chrome Dev Tools

You will most likely see a window open on the bottom of your browser with bunches of buttons, sub-windows and a console.

JavaScript Console

The JavaScript console provides you with an interface to execute code in the context of the currently loaded page. This means that any libraries or code that are available to your global scope, i.e. window, are available to you in the console.

If you navigate to the Console link on the demo while the console is open you should see some messages like the following:

Console Logging

Open up js/console.js and you'll see this code:

// Console


console.log("I'm some informative logging information.");

console.warn("I'm a more serious warning you might want to pay attention to...");

console.error("I broke...");

This should be fairly transparent but it shows you that you have various levels of logging available to you in your JavaScript code. You have console.log for plain logs that are more for just debugging and information. There's console.warn which is good for bringing things to the attention of other developers. For example, you might warn that a method or property is deprecated. Finally, there is console.error which shows a red error message with a stack trace.

The following code is in the file for you to play with! This function is declared in the global namespace and available for you to call via the console.

var hackMe = function() {
  console.log('You must have accessed me from the console huh?');
  return 'Cool?';
};

When you run var response = hackMe(); in the console, it will output the message and return 'Cool?'.

Console Features

Try running some other functions and make some variables in the console. It's a gift and a curse. It allows you to explore code live on the page but be aware, this means others can do the same with code you've written and deployed!

The Debugger

On to the debugger. A debugger allows you to stop your program and run it frame by frame. Each frame you can view exactly what the variables in the current scope are and see they're current values!

Debugger

But there's much more! You can also open up your JavaScript source and set breakpoints that allow you to stop at a particular point or many points of your choosing.

Navigate to Source and notice the file system of loaded scripts.

Viewing Source

Setting Break Points

Now you can set breakpoints on any line of code to stop execution there. Have a look at js/break-points.js:

// Break Points


var BreakPoints = function() {

  var a = 1,
      b = 2,
      c,
      d;

  console.log(this);
  console.log('Set a break point here.');
  console.log('You should see values for a and b, but not for c and d');
  console.log('You will also see `this` is the window object');

  function doCoolThing() {
    a = 'Cool';
    b = 'Awesome';
    console.log(this);
    c = 'Gnarly';
    d = 'Tubular';

    console.log('Set a break point here');
    console.log('Now a, b, c, and d all have string values');
    console.log('Also `this` should now be set to `myObject`');
  };

  var myObject = { foo: 'bar' };

  doCoolThing.call(myObject);

};


BreakPoints();

If you set breakpoints at the places recommended by the console.log calls you'll get a glimpse into the scope of the program at that point in time. You'll notice that there are two of these recommended places.

Paused in Debugger

As you create breakpoints they will appear in the list of created breakpoints with the line number and code at that line.

Break Points List

You'll also notice the Scope window that allows you to see the local variables, global variables and the current value of this.

Current Scope

You can imagine how important it is to be able to put your code under a microscope when you really need to know what is going on.

The Call Stack

Call stacks are so helpful, they're like breadcrumbs leading back to the origin of that nasty error you're getting for some odd reason.

The call stack can be seen in the debugger when a breakpoint is hit.

Debugger Call Stack Break Points

As you can see, it is very informative. It tells us the chronological order of functions called up to the last call and what lines they were called on.

Debugger Call Stack

The console also logs the call stack under an error message when an error is thrown.

Console Error Call Stack

Looking at js/call-stack.js you can see the exact path the call stack is tracing back from the thrown error.

NOTE: Errors that are thrown in minified code will not show reliable line numbers in their call stacks. This is why most libraries suggest using development versions which are un-minified. For example the jQuery development version.

// Call Stack


var zero,
    one,
    two,
    three;

console.log(zero, one, two, three);

zero = function() {
  var a = 'Cool!';
  var b = 'Gnarly!';
  console.log('zero');
  throw new Error("Uh oh...");
};

one = function() {
  zero.call({});
  console.log('one');
};

two = function() {
  one();
  console.log('two');
};

three = function() {
  two();
  console.log('three');
};


var onLoad = function() {
  three();
};


window.addEventListener('load', onLoad);

JavaScript can be silent when it breaks. Call stacks are your loud friend that tells you great information about what went wrong and where.

Timeline

The Timeline tells you detailed information about what features and functions on your page loading and rendering are most computationally intensive. This is awesome. You can actually boil down into your code and find exact lines that are slowing down your rendering and user interaction.

Timeline

Here is a great example video of Google Chrome being used to improve performance.

Network

The Network panel is going to show you all and more than you want to know about the requests made to load your page. This includes loading assets, images, audio, video, and files. It shows you load times, status codes, mime-types and more.

Network

Conclusion

Now you should have a much better understanding of how to use your developer tools to debug JavaScript and a great place to start for diving deeper into tightening up the performance of your front end code. The detailed features of Chrome Developer Tools are rich and provide a professional interface for profiling your applications. For more details check out Google's documentation on their Developer Tools.

Octocat 300


Sign up to track your progress for free

There are ( ) additional resources for this lesson. Check them out!

Sorry, comments aren't active just yet!

Next Lesson: Test Yourself: jQuery Basics