Home / AJAX

Cross-Browser Peculiaraties

RSS
Modified on 2009/12/14 23:48 by Stephen Walther Categorized as Uncategorized
It should come as no surprise to any web developers that different browsers implement the JavaScript language and run-time differently. Most of the time they are pretty much in-sync with only minor variations or differences in object model implementations. However, there are a number of arcane differences that if not watched carefully, can lead to very difficult bugs to diagnose in different browsers. Microsoft Ajax Minifier will attempt to flag those differences as errors so the developer will be encouraged not to engage in paradigms that will cause such problems.

Ambiguous Try/Catch Variables

All browsers except IE define the name of the error variable in the catch block within the catch block itself. IE defines the variable within the containing scope. This can lead to ambiguous references that will behave differently in different browsers. For example:

var a, e = 10;
try
{
    // force an error
    a = foo;
}
catch(e)
{
    // error handling
}
alert(e);

In IE, there is only one variable named “e,” and the alert will be the “undefined variable ‘foo’” error. In all other browsers, the error object is scoped to the catch block only, and does not affect the variable defined in the containing scope; therefore the alert shows 10.

This code will throw an “ambiguous catch variable” error in Microsoft Ajax Minifier. If the developer wishes to produce solid code that works the same in all modern browsers, he should make sure the name of the error variable in the catch block is not the same as a variable referenced in the containing scope. The above code should be written as:

var a, e = 10;
try
{
    // force an error
    a = e / 0;
}
catch(err) // name should not collide with containing scope
{
    // error handling
}
alert(e);

Ambiguous Named Function Expressions

Named function expressions have the same problem. All browsers save IE allow the name of the function expression to be scoped only to the function expression’s scope, thereby allowing recursive calls to be made. IE defines the name of the expression in the containing scope. The same problems can occur:

var foo = 10;
(function foo(cnt){
    if (--cnt > 0)
    {
        foo(cnt)
    }
})(10);
alert(foo);

All browsers but IE will properly run this code because the variable foo defined in the outer scope is not the same foo defined within the function expression scope. The inner call will recurse for 10 iterations, and then the alert will show 10. This code will not execute in IE! This is because for IE, there is only one field named foo. When the code is parsed, the function expression creates the field “foo” in the outer scope and assigned it the value of the function expression. Once execution begins, the first var statement sets that field to the value 10. The first time the function expression is run, it tries to recurse by executing the value of “foo” as a function – but it’s no longer a function; it’s the value 10 and an error is produced.

Microsoft Ajax Minifier will detect when a named function expression collides with a variable referenced in the containing scope, and will throw an error so the developer will know that the code will behave differently in different browsers.