Debugging Web(4) – Swiss Army Knives

Web December 28th, 2006

Web Developer Toolbar and Firebug are two must-haves for the Web developers, I will introduce another powerful debugger, venkman later.

Web Developer Toolbar

Yellow box

This all-in-one toolbar gears towards getting the Web designer out of the tedious work, such as fine-tuning CSS, troubleshooting block layout, validating to the Web standards. My favorite functionality is Display Element Informaton, the Ctrl-Shift-f shortcut will call a yellow box, once the element is clicked, its attributes are shown in the yellow box, quite nifty.

FireBug

The official website have a very detailed introduction of the FireBug. Further more, the prototype’s author demonstrates the FireBug in action here. Unlike Error Console, the FireBug expose the targeted window’s document node to the global scope, therefore, the developer can test the JavaScript code snippet in the console without hassle.

The console supports one-line command, when you click the Up button on the right, a multi-line textbox is popped out for multiply line code editing. What a considerate design!

FireBug's console


Debugging Web(3) – Poor man’s debugger

Web December 18th, 2006

This post is for the real poor Web developers who even could not install add-ons on Firefox, at least, there are two spartan debuggers available:

DOM Inspector

A neat tool to demonstrate the DOM structure of the Web page. It is far less attractive than the Web Developer Toolbar’s Display Element Information. However, you might find it useful to inspect the add-on’s XUL.

DOM Inspector in action


Error Console

Error Console supports to evaluate the JavaScript snippet directly. However, the targeted window’s document is not exposed in the global scope, that cripple the usability of this tool and push me to embrace FireBug.
Please leave a comment if I am wrong.

Debugging Web(2) – 10 Pitfalls for the JavaScript Developers

Web December 11th, 2006

Strictly, this post does not belong to this category. But on the other hand, the following pitfalls are usually the evil source.

Note: the code is intentionally to put in one line, just for your convenience to test it in the FireBug.

1. Unexpected global variables

Declare a variable via var state at any time, whether this variable is in the global scope or local scope. Any variable without declaration resides in the global scope, polluting the global namespace.

2. Caution: Boolean operation ahead

JavaScript is extremely tolerate for the type checking, raising an exception is the last thing the interpreter wants to do. The inherent conversion may surprise you especially for the C/C++ programmer. For example,

if (new Boolean(false)) alert("true");

Although the constructed Boolean object is false, the if expression returns true. Why? Because the Boolean is an object, if it is not null, the expression returns true.

Here is another example used in the vararg functions: if (arg5 != null) ; C/C++ programmer may jump to the old trick:if (p), Oops, this expression could not differentiate whether p is null or 0 or “” . JavaScript: The Definitive Guide, 5th Edition Section 5.4 disclose the conversion rule for the == operator:

If the two values have the same type, test them for identity. If the values are identical, they are equal; if they are not identical, they are not equal.
If the two values do not have the same type, they may still be equal. Use the following rules and type conversions to check for equality:
If one value is null and the other is undefined, they are equal.
If one value is a number and the other is a string, convert the string to a number and try the comparison again, using the converted value.
If either value is TRue, convert it to 1 and try the comparison again. If either value is false, convert it to 0 and try the comparison again.
If one value is an object and the other is a number or string, convert the object to a primitive and try the comparison again. An object is converted to a primitive value by either its toString( ) method or its valueOf( ) method. The built-in classes of core JavaScript attempt valueOf( ) conversion before toString( ) conversion, except for the Date class, which performs toString( ) conversion. Objects that are not part of core JavaScript may convert themselves to primitive values in an implementation-defined way.
Any other combinations of values are not equal.

typeof operator is also a safe approach, like if (typeof(arg5) == “undefined”)

3. valueOf vs. toString

When JavaScript convert an object to string, the toString function is hidden by valueOf, the valueOf is evaluated, then convert the result to string, like this:

>>> function Foo() {}; Foo.prototype.valueOf = function() { return 3;}; Foo.prototype.toString = function() { return "bar";}; var x = "foo" + new Foo(); x;
"foo3"

The only exception is Date, the toString is used in + operator, while valueOf is used in the comparison.

4. Immutable String

JavaScript takes this approach to pass the argument to the function: pass by value for primitive data types, pass by reference for objects. String is regarded as the object, but passed by the value:

>>> function foo(s) { s[0] = ‘t’;}; var x="hello"; foo(x); x;
"hello"

5. Pervasive scope

For C/C++ developer, the declared variable take effects after its declaration, like this:

#include <stdio.h>
int x = 9;

int foo()
{
        printf("x =%d\n", x);
        int x = 10;
        printf("x =%d\n", x);
        return 0;
}

int main()
{
        return foo();
}

the output is

x =9
x =10

While in JavaScript, once the variable is declared, it is populated to the whole closure, for instance:

var  x= 9; function foo() { alert(x); var x = 10;  alert(x); }; foo();

The alerts are undefined and 10. The global value x is shadowed by the local variable x. Local variable x is declared in this closure, but not assigned before the first alert, so its value is undefined.

TO BE CONTINUED…