PDA

View Full Version : How do you debug js?



mjlecomte
3 Apr 2008, 5:52 PM
I'm not looking for "use firebug".

I happen to be self taught and am doing web application development on the side. So I do not have any formal training nor an office of other skilled / seasoned people to help out with tips/tricks etc. Anything I know (apparently not much still) is through this forum and reading books. Ext JS launched my interest in javascript. Period. So my first exposure (for better or worse) is here. Worse meaning I ask a lot of stupid questions, etc.

I've only managed to find maybe one 'how to use firebug' type screencast, so I'm sure I'm missing out on some features.

It's not for "ext" to teach javascript, but perhaps some tutorials or links to 'how to debug' would be helpful? I've read books (yes plural) on js (Flanagan's, Pro techniques, etc.), watched Crock's videos (I need to go back), but none really provided tips on debugging. Perhaps debugging should be universal to all languages, but I find myself stumbling a bit, perhaps because of by infancy with programming and js in particular.

Anyway, if anyone stumbles across this and wants to point me in a direction (hopefully not out the door :) ), would be appreciated.

Basically looking for any tips/tricks, etc. to using firebug or screencasts on same, or just debugging techniques for js in general.

My firesuit is at the cleaners, please be kind. :">

evant
3 Apr 2008, 5:58 PM
I swear a lot :D

In all seriousness, I've never needed to go much further than viewing responses in FireBug or the odd browse through the source.

I find the best way to solve problems is simplifying the test case and going from there.

Animal
4 Apr 2008, 12:08 AM
If you can use Firebug to set breakpoints, step through code, follow the call stack backwards, examine variables, and use the console command line, then you've pretty much got it sussed.

mirage
4 Apr 2008, 8:50 AM
I know how you feel. Learning about firebug (as any dev-tool) is a task of it's own. I still discover new features in it all the time. Same as with Ext - reading on how to use Firebug and how other people use it is the best way to learn.

A good place to get started - if you haven't explored it yet:
http://extjs.com/learn/Manual:Resources#Firebug

I mostly use the firebug Console to output debugging info and sometimes to query ext objects I created to examine their properties at a given state. I also use the XHR logging in the console to examine my server responses.

I run this little piece of code in my main app script to avoid console.debug 'issues' on other browsers in case I forget to comment out a debug instruction here and there:


if (! ("console" in window) || !("firebug" in console)) {
var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group"
, "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
window.console = {};
for (var i = 0; i <names.length; ++i) window.console[names[i]] = function() {};
}


If you have more specific needs / questions, fire away.

Cheers!

mjlecomte
4 Apr 2008, 9:00 AM
Thanks all.

Good tip Mirage. Yeah, I use console.log a lot to 'learn' and track what is going on when, etc. I'll investigate your procedure, will definitely be helpful.

I've noticed when using console.log and doing:


console.log('hey dude, you're at this spot and this = ', this);

gives inaccurate results. I presume this to be an issue with firebug. If you set breakpoints and check this at execution time, what this is, is not the same as when you review the log when the code finishes execution and you go back and inspect the dom of the various logged variables. Most other objects appear to be true to form, although I'm not sure. But this for sure is different. As far as I can tell typically this refers to whatever the last state of this was when last requested.

So I guess my question is, is there a good/better way to track what this is other than stepping through? At this point in my learning, I think the scope of this is what hangs me up the most, hence my attempts to study further through firebug.

mirage
4 Apr 2008, 9:11 AM
mj -

Not sure about 'this' :-). I tend not to use 'this'. It confuses me in Javascript

But I've noticed what you say on other objects. E.g. I was debugging an Ext.Record object before I updated it. The output in the console however reflected the updated state. So Firebug must be updating changes objects in the console as it goes.

Ergo the same probably applies to 'this'. Not sure if that's a bug tho.

Cheers!

mjlecomte
4 Apr 2008, 9:18 AM
Well, next time you think about it, log this at the beginning, inside some functions, at the end, etc. where you know this should be different and you may see what I mean. Other objects seem to be accurate. So if I request a store object at various points in execution I believe it tends to accurately represent the store's state at that point. So far I've really only noticed the discrepancy with this. My contention is that if you go back in the log and review 6 reports of this, that many or all will show the same state of the object (and if you step along in firebug I have verified that the state is different at execution time).

Rich Kucera
4 Apr 2008, 9:32 AM
general advice: hard code, break it down by substituting constants...work out real way later. stub out complex dependencies, simplify, reduce, minimize, sketch, mock, hack, solve the simpler problem. breakpoint, inspect and hack stuff in the console. it's all in the tests you devise...do your practice, all is coming. (ah, yeah, debugging is "heuristic" activity, look that up).

The real hard bugs, like stuff that causes low-level exceptions in browsers, is usually to be got from forums. I have no idea how they find out that info, other than trying out on several browsers and seeing differences. Sometimes you can thank IE because it will tell you "Out of Memory" when Firefox will just sit there and say nothing leaving you to start cursing. Both browsers suck, in different ways. At times I've cursed firefox and thanked IE, mostly the other way around...

a couple things may be handy:

When you have to look at stuff in IE, this could be handy and enlightening
http://www.twinhelix.com/javascript/objbrowser/

This snippet may be handy (though there are lots of object inspectors out there).



/**
* TrimPath.breakpoint usage:
*
* In the middle of your code somewhere, add a line of code like...
*
* breakpoint(function(expr) { return eval(expr); });
*
* You can also pass a message, like...
*
* breakpoint(function(expr) { return eval(expr); }, "breakpoint #2 in datetime validation");
*
* You can also pass in an initial expression as the 3rd parameter, like...
*
* breakpoint(function(expr) { return eval(expr); }, "breakpoint #2 in datetime validation", "dateStr");
*
* Then, you can enter expressions in the prompt dialog to inspect variables and objects
* in the breakpoint's scope. Click Cancel in the prompt dialog to continue processing.
*/
var breakpoint = TrimPath.breakpoint = function(evalFunc, msg, initialExprStr) {
// TrimPath.breakpoint currently works only in DOM/browser environment.
if (msg == null)
msg = "";
var result = initialExprStr || "1+2";
while (true) {
var expr = prompt("BREAKPOINT: " + msg + "\nEnter an expression to evaluate, or Cancel to continue.", result);
if (expr == null || expr == "")
return;
try {
result = evalFunc(expr);
} catch (e) {
result = e;
}
}
}

var inspect = TrimPath.inspect = function(obj) {

var report_str = "";
k = 1;
for ( var key in obj ) {
nlchar = (( k % 3 )==0)?'\n':'..........';
if ( obj.getAttribute ) {
report_str += key+ ": " + obj.getAttribute(key) + nlchar; //IE
} else {
report_str += key + nlchar; //Firefox
}
k++;
}
return report_str;
}

var inspectStyle = TrimPath.inspectStyle = function(elm){
if (elm.style){
var str = "";
k = 1;
for (var i in elm.style){
nlchar = (( k % 3 )==0)?'\n':'..........';
str += i + ": " + elm.style[i] + nlchar;
k++;
}
return str;
}
}

mjlecomte
5 Apr 2008, 6:25 AM
I've noticed when using console.log and doing:


console.log('hey dude, you're at this spot and this = ', this);

gives inaccurate results.

RTFM! http://www.getfirebug.com/logging.html



console.log('using log to show this is BAD. this = ', this);//only shows final condition of this

//use this instead:
console.dir(this);//this IS accurate at the time the line is executed

//also cool:
console.trace();//show the stack trace at the time this line is executed.

//use this to manage the output better:
console.group('some group name'); //makes foldable regions of the console report

dj
5 Apr 2008, 5:57 PM
if (! ("console" in window) || !("firebug" in console)) {
var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group"
, "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
window.console = {};
for (var i = 0; i <names.length; ++i) window.console[names[i]] = function() {};
}



I use a slightly modified version of firebugx.js


(function(){
// firebugx.js optimized for compressability and Safari
var win = window, emptyFn = function(){}, names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
if (!win.console) {
win.console = {};
}
var console = win.console;
for (var i = 0; i < names.length; ++i) {
if (!console[names[i]]) {
console[names[i]] = emptyFn;
}
}
})();


Advantages:

no global variable polution
can be better compressed with YUI-Compressor or Shrinksafe (every byte counts! ;) )
does not overwrites Safaris console.log()

dj
5 Apr 2008, 6:36 PM
mj -

But I've noticed what you say on other objects. E.g. I was debugging an Ext.Record object before I updated it. The output in the console however reflected the updated state. So Firebug must be updating changes objects in the console as it goes.

Ergo the same probably applies to 'this'. Not sure if that's a bug tho.


That is not a bug. console.log will give you a reference to that object. Only by the time you actually click that object-link, the reference will be evaluated. BTW: That makes Firefox consuming more memory with enabled Firebug because Firebug needs to hold a reference to the logged object and the JavaScript Garbage Collector cannot delete the object. So if you do a lot of logging with object-links you should reload the page from time to time.



Another handy tip with Firebug's logging:
Implement the toString() method of a class and Firebug will print the returned string instead of "Object".

I quickly copy&pasted nearly all classes from the API Documentation and added a toString to them:


Ext.override(Ext.Action, { toString: function(){ return 'Ext.Action'; }});
Ext.override(Ext.BoxComponent, { toString: function(){ return 'Ext.BoxComponent'; }});
Ext.override(Ext.Button, { toString: function(){ return 'Ext.Button'; }});
Ext.override(Ext.ColorPalette, { toString: function(){ return 'Ext.ColorPalette'; }});
Ext.override(Ext.Component, { toString: function(){ return 'Ext.Component'; }});
Ext.override(Ext.CompositeElement, { toString: function(){ return 'Ext.CompositeElement'; }});
Ext.override(Ext.CompositeElementLite, { toString: function(){ return 'Ext.CompositeElementLite'; }});
Ext.override(Ext.Container, { toString: function(){ return 'Ext.Container'; }});
Ext.override(Ext.CycleButton, { toString: function(){ return 'Ext.CycleButton'; }});
Ext.override(Ext.DataView, { toString: function(){ return 'Ext.DataView'; }});
Ext.override(Ext.DatePicker, { toString: function(){ return 'Ext.DatePicker'; }});
Ext.override(Ext.Editor, { toString: function(){ return 'Ext.Editor'; }});
Ext.override(Ext.Element, { toString: function(){ return 'Ext.Element'; }});
Ext.override(Ext.KeyMap, { toString: function(){ return 'Ext.KeyMap'; }});
Ext.override(Ext.KeyNav, { toString: function(){ return 'Ext.KeyNav'; }});
Ext.override(Ext.Layer, { toString: function(){ return 'Ext.Layer'; }});
Ext.override(Ext.LoadMask, { toString: function(){ return 'Ext.LoadMask'; }});
Ext.override(Ext.PagingToolbar, { toString: function(){ return 'Ext.PagingToolbar'; }});
Ext.override(Ext.Panel, { toString: function(){ return 'Ext.Panel'; }});
Ext.override(Ext.ProgressBar, { toString: function(){ return 'Ext.ProgressBar'; }});
Ext.override(Ext.QuickTip, { toString: function(){ return 'Ext.QuickTip'; }});
Ext.override(Ext.Resizable, { toString: function(){ return 'Ext.Resizable'; }});
Ext.override(Ext.Shadow, { toString: function(){ return 'Ext.Shadow'; }});
Ext.override(Ext.SplitBar, { toString: function(){ return 'Ext.SplitBar'; }});
Ext.override(Ext.SplitBar.AbsoluteLayoutAdapter, { toString: function(){ return 'Ext.SplitBar.AbsoluteLayoutAdapter'; }});
Ext.override(Ext.SplitBar.BasicLayoutAdapter, { toString: function(){ return 'Ext.SplitBar.BasicLayoutAdapter'; }});
Ext.override(Ext.SplitButton, { toString: function(){ return 'Ext.SplitButton'; }});
Ext.override(Ext.TabPanel, { toString: function(){ return 'Ext.TabPanel'; }});
Ext.override(Ext.Template, { toString: function(){ return 'Ext.Template'; }});
Ext.override(Ext.Tip, { toString: function(){ return 'Ext.Tip'; }});
Ext.override(Ext.ToolTip, { toString: function(){ return 'Ext.ToolTip'; }});
Ext.override(Ext.Toolbar, { toString: function(){ return 'Ext.Toolbar'; }});
Ext.override(Ext.Toolbar.Button, { toString: function(){ return 'Ext.Toolbar.Button'; }});
Ext.override(Ext.Toolbar.Fill, { toString: function(){ return 'Ext.Toolbar.Fill'; }});
Ext.override(Ext.Toolbar.Item, { toString: function(){ return 'Ext.Toolbar.Item'; }});
Ext.override(Ext.Toolbar.Separator, { toString: function(){ return 'Ext.Toolbar.Separator'; }});
Ext.override(Ext.Toolbar.Spacer, { toString: function(){ return 'Ext.Toolbar.Spacer'; }});
Ext.override(Ext.Toolbar.SplitButton, { toString: function(){ return 'Ext.Toolbar.SplitButton'; }});
Ext.override(Ext.Toolbar.TextItem, { toString: function(){ return 'Ext.Toolbar.TextItem'; }});
Ext.override(Ext.Updater, { toString: function(){ return 'Ext.Updater'; }});
Ext.override(Ext.Updater.BasicRenderer, { toString: function(){ return 'Ext.Updater.BasicRenderer'; }});
Ext.override(Ext.Viewport, { toString: function(){ return 'Ext.Viewport'; }});
Ext.override(Ext.Window, { toString: function(){ return 'Ext.Window'; }});
Ext.override(Ext.WindowGroup, { toString: function(){ return 'Ext.WindowGroup'; }});
Ext.override(Ext.XTemplate, { toString: function(){ return 'Ext.XTemplate'; }});
Ext.override(Ext.data.ArrayReader, { toString: function(){ return 'Ext.data.ArrayReader'; }});
Ext.override(Ext.data.Connection, { toString: function(){ return 'Ext.data.Connection'; }});
Ext.override(Ext.data.DataProxy, { toString: function(){ return 'Ext.data.DataProxy'; }});
Ext.override(Ext.data.DataReader, { toString: function(){ return 'Ext.data.DataReader'; }});
Ext.override(Ext.data.GroupingStore, { toString: function(){ return 'Ext.data.GroupingStore'; }});
Ext.override(Ext.data.HttpProxy, { toString: function(){ return 'Ext.data.HttpProxy'; }});
Ext.override(Ext.data.JsonReader, { toString: function(){ return 'Ext.data.JsonReader'; }});
Ext.override(Ext.data.JsonStore, { toString: function(){ return 'Ext.data.JsonStore'; }});
Ext.override(Ext.data.MemoryProxy, { toString: function(){ return 'Ext.data.MemoryProxy'; }});
Ext.override(Ext.data.Node, { toString: function(){ return 'Ext.data.Node'; }});
Ext.override(Ext.data.Record, { toString: function(){ return 'Ext.data.Record'; }});
Ext.override(Ext.data.ScriptTagProxy, { toString: function(){ return 'Ext.data.ScriptTagProxy'; }});
Ext.override(Ext.data.SimpleStore, { toString: function(){ return 'Ext.data.SimpleStore'; }});
Ext.override(Ext.data.Store, { toString: function(){ return 'Ext.data.Store'; }});
Ext.override(Ext.data.Tree, { toString: function(){ return 'Ext.data.Tree'; }});
Ext.override(Ext.data.XmlReader, { toString: function(){ return 'Ext.data.XmlReader'; }});
Ext.override(Ext.dd.DD, { toString: function(){ return 'Ext.dd.DD'; }});
Ext.override(Ext.dd.DDProxy, { toString: function(){ return 'Ext.dd.DDProxy'; }});
Ext.override(Ext.dd.DDTarget, { toString: function(){ return 'Ext.dd.DDTarget'; }});
Ext.override(Ext.dd.DragDrop, { toString: function(){ return 'Ext.dd.DragDrop'; }});
Ext.override(Ext.dd.DragSource, { toString: function(){ return 'Ext.dd.DragSource'; }});
Ext.override(Ext.dd.DragZone, { toString: function(){ return 'Ext.dd.DragZone'; }});
Ext.override(Ext.dd.DropTarget, { toString: function(){ return 'Ext.dd.DropTarget'; }});
Ext.override(Ext.dd.DropZone, { toString: function(){ return 'Ext.dd.DropZone'; }});
Ext.override(Ext.dd.StatusProxy, { toString: function(){ return 'Ext.dd.StatusProxy'; }});
Ext.override(Ext.form.Action, { toString: function(){ return 'Ext.form.Action'; }});
Ext.override(Ext.form.Action.Load, { toString: function(){ return 'Ext.form.Action.Load'; }});
Ext.override(Ext.form.Action.Submit, { toString: function(){ return 'Ext.form.Action.Submit'; }});
Ext.override(Ext.form.BasicForm, { toString: function(){ return 'Ext.form.BasicForm'; }});
Ext.override(Ext.form.Checkbox, { toString: function(){ return 'Ext.form.Checkbox'; }});
Ext.override(Ext.form.ComboBox, { toString: function(){ return 'Ext.form.ComboBox'; }});
Ext.override(Ext.form.DateField, { toString: function(){ return 'Ext.form.DateField'; }});
Ext.override(Ext.form.Field, { toString: function(){ return 'Ext.form.Field'; }});
Ext.override(Ext.form.FieldSet, { toString: function(){ return 'Ext.form.FieldSet'; }});
Ext.override(Ext.form.FormPanel, { toString: function(){ return 'Ext.form.FormPanel'; }});
Ext.override(Ext.form.Hidden, { toString: function(){ return 'Ext.form.Hidden'; }});
Ext.override(Ext.form.HtmlEditor, { toString: function(){ return 'Ext.form.HtmlEditor'; }});
Ext.override(Ext.form.NumberField, { toString: function(){ return 'Ext.form.NumberField'; }});
Ext.override(Ext.form.Radio, { toString: function(){ return 'Ext.form.Radio'; }});
Ext.override(Ext.form.TextArea, { toString: function(){ return 'Ext.form.TextArea'; }});
Ext.override(Ext.form.TextField, { toString: function(){ return 'Ext.form.TextField'; }});
Ext.override(Ext.form.TimeField, { toString: function(){ return 'Ext.form.TimeField'; }});
Ext.override(Ext.form.TriggerField, { toString: function(){ return 'Ext.form.TriggerField'; }});
Ext.override(Ext.grid.AbstractSelectionModel, { toString: function(){ return 'Ext.grid.AbstractSelectionModel'; }});
Ext.override(Ext.grid.CellSelectionModel, { toString: function(){ return 'Ext.grid.CellSelectionModel'; }});
Ext.override(Ext.grid.CheckboxSelectionModel, { toString: function(){ return 'Ext.grid.CheckboxSelectionModel'; }});
Ext.override(Ext.grid.ColumnModel, { toString: function(){ return 'Ext.grid.ColumnModel'; }});
Ext.override(Ext.grid.EditorGridPanel, { toString: function(){ return 'Ext.grid.EditorGridPanel'; }});
Ext.override(Ext.grid.GridPanel, { toString: function(){ return 'Ext.grid.GridPanel'; }});
Ext.override(Ext.grid.GridView, { toString: function(){ return 'Ext.grid.GridView'; }});
Ext.override(Ext.grid.GroupingView, { toString: function(){ return 'Ext.grid.GroupingView'; }});
Ext.override(Ext.grid.PropertyColumnModel, { toString: function(){ return 'Ext.grid.PropertyColumnModel'; }});
Ext.override(Ext.grid.PropertyGrid, { toString: function(){ return 'Ext.grid.PropertyGrid'; }});
Ext.override(Ext.grid.PropertyRecord, { toString: function(){ return 'Ext.grid.PropertyRecord'; }});
Ext.override(Ext.grid.PropertyStore, { toString: function(){ return 'Ext.grid.PropertyStore'; }});
Ext.override(Ext.grid.RowNumberer, { toString: function(){ return 'Ext.grid.RowNumberer'; }});
Ext.override(Ext.grid.RowSelectionModel, { toString: function(){ return 'Ext.grid.RowSelectionModel'; }});
Ext.override(Ext.layout.AbsoluteLayout, { toString: function(){ return 'Ext.layout.AbsoluteLayout'; }});
Ext.override(Ext.layout.Accordion, { toString: function(){ return 'Ext.layout.Accordion'; }});
Ext.override(Ext.layout.AnchorLayout, { toString: function(){ return 'Ext.layout.AnchorLayout'; }});
Ext.override(Ext.layout.BorderLayout, { toString: function(){ return 'Ext.layout.BorderLayout'; }});
Ext.override(Ext.layout.BorderLayout.Region, { toString: function(){ return 'Ext.layout.BorderLayout.Region'; }});
Ext.override(Ext.layout.BorderLayout.SplitRegion, { toString: function(){ return 'Ext.layout.BorderLayout.SplitRegion'; }});
Ext.override(Ext.layout.CardLayout, { toString: function(){ return 'Ext.layout.CardLayout'; }});
Ext.override(Ext.layout.ColumnLayout, { toString: function(){ return 'Ext.layout.ColumnLayout'; }});
Ext.override(Ext.layout.ContainerLayout, { toString: function(){ return 'Ext.layout.ContainerLayout'; }});
Ext.override(Ext.layout.FitLayout, { toString: function(){ return 'Ext.layout.FitLayout'; }});
Ext.override(Ext.layout.FormLayout, { toString: function(){ return 'Ext.layout.FormLayout'; }});
Ext.override(Ext.layout.TableLayout, { toString: function(){ return 'Ext.layout.TableLayout'; }});
Ext.override(Ext.menu.Adapter, { toString: function(){ return 'Ext.menu.Adapter'; }});
Ext.override(Ext.menu.BaseItem, { toString: function(){ return 'Ext.menu.BaseItem'; }});
Ext.override(Ext.menu.CheckItem, { toString: function(){ return 'Ext.menu.CheckItem'; }});
Ext.override(Ext.menu.ColorItem, { toString: function(){ return 'Ext.menu.ColorItem'; }});
Ext.override(Ext.menu.ColorMenu, { toString: function(){ return 'Ext.menu.ColorMenu'; }});
Ext.override(Ext.menu.DateItem, { toString: function(){ return 'Ext.menu.DateItem'; }});
Ext.override(Ext.menu.DateMenu, { toString: function(){ return 'Ext.menu.DateMenu'; }});
Ext.override(Ext.menu.Item, { toString: function(){ return 'Ext.menu.Item'; }});
Ext.override(Ext.menu.Menu, { toString: function(){ return 'Ext.menu.Menu'; }});
Ext.override(Ext.menu.Separator, { toString: function(){ return 'Ext.menu.Separator'; }});
Ext.override(Ext.menu.TextItem, { toString: function(){ return 'Ext.menu.TextItem'; }});
Ext.override(Ext.state.CookieProvider, { toString: function(){ return 'Ext.state.CookieProvider'; }});
Ext.override(Ext.state.Provider, { toString: function(){ return 'Ext.state.Provider'; }});
Ext.override(Ext.tree.AsyncTreeNode, { toString: function(){ return 'Ext.tree.AsyncTreeNode'; }});
Ext.override(Ext.tree.DefaultSelectionModel, { toString: function(){ return 'Ext.tree.DefaultSelectionModel'; }});
Ext.override(Ext.tree.MultiSelectionModel, { toString: function(){ return 'Ext.tree.MultiSelectionModel'; }});
Ext.override(Ext.tree.RootTreeNodeUI, { toString: function(){ return 'Ext.tree.RootTreeNodeUI'; }});
Ext.override(Ext.tree.TreeDragZone, { toString: function(){ return 'Ext.tree.TreeDragZone'; }});
Ext.override(Ext.tree.TreeDropZone, { toString: function(){ return 'Ext.tree.TreeDropZone'; }});
Ext.override(Ext.tree.TreeEditor, { toString: function(){ return 'Ext.tree.TreeEditor'; }});
Ext.override(Ext.tree.TreeFilter, { toString: function(){ return 'Ext.tree.TreeFilter'; }});
Ext.override(Ext.tree.TreeLoader, { toString: function(){ return 'Ext.tree.TreeLoader'; }});
Ext.override(Ext.tree.TreeNode, { toString: function(){ return 'Ext.tree.TreeNode'; }});
Ext.override(Ext.tree.TreeNodeUI, { toString: function(){ return 'Ext.tree.TreeNodeUI'; }});
Ext.override(Ext.tree.TreePanel, { toString: function(){ return 'Ext.tree.TreePanel'; }});
Ext.override(Ext.tree.TreeSorter, { toString: function(){ return 'Ext.tree.TreeSorter'; }});
Ext.override(Ext.util.ClickRepeater, { toString: function(){ return 'Ext.util.ClickRepeater'; }});
Ext.override(Ext.util.DelayedTask, { toString: function(){ return 'Ext.util.DelayedTask'; }});
Ext.override(Ext.util.MixedCollection, { toString: function(){ return 'Ext.util.MixedCollection'; }});
Ext.override(Ext.util.Observable, { toString: function(){ return 'Ext.util.Observable'; }});
Ext.override(Ext.util.TaskRunner, { toString: function(){ return 'Ext.util.TaskRunner'; }});

if (Ext.isAir) {
Ext.override(Ext.air.FileProvider, { toString: function(){ return 'Ext.air.FileProvider'; }});
Ext.override(Ext.air.NativeObservable, { toString: function(){ return 'Ext.air.NativeObservable'; }});
Ext.override(Ext.air.NativeWindow, { toString: function(){ return 'Ext.air.NativeWindow'; }});
Ext.override(Ext.air.NativeWindowGroup, { toString: function(){ return 'Ext.air.NativeWindowGroup'; }});
}


when you now do a

console.log(this);
you will at least see of which type the object is.

mirage
5 Apr 2008, 8:40 PM
Thanks dj -
Those are all great tips!

mystix
8 Apr 2008, 9:30 AM
ooh... found something new -- pi.debugger:
http://code.google.com/p/pi-js/

supposedly works cross-browser. looks interesting... if anyone tries it before lazy me, pls, post your findings back in this thread. :)

ChapterHouse
8 Apr 2008, 12:22 PM
I also find that in addition to Firebug I use the debugger in Aptana Studio (http://www.aptana.com/studio) a lot. The free community edition does javascript FireFox debugging. The pro version adds in IE debugging. I didn't figure I would use it much when I bought it. I was more just supporting the project. But in the last three weeks it has paid for itself in the number of headaches I was able to solve with IE. I would recommend checking out the free version. I am not much for code completion, but the latest versions do have that for Ext 2 if you are into that sort of thing.

ZeusTheTrueGod
9 Apr 2008, 3:14 AM
log4javascript could be intresting. you can log to every possible place,include server with ajax