Bitten by IE8

2014-04-04

Yesterday, there was an embarrassing JavaScript error in some piece of functionality in our product at work.

To make it even worse, it appeared I had authored the excact row where things broke. To make it even worse, it was where I had made a somewhat lame effort to be robust.

It was about trying to handle the second (optional) parameter to a function - an options object. Instead of some standard (sloppy) cast-to-boolean check:

1options || (options = {}); // kinda works

, I had decided to to act like some kind of grown up or something and avoid traps in the form of true , " " and 1 etc., like so:

1function foo(url, options) {
2
3    // did we get any options object? if not, create an empty one
4    "[object Object]" == ({}).toString.call(options) || (options = {});
5    // append some parameter if it was given in options
6    "undefined" == typeof options.id || (url += "&id" + options.id);
7
8}

Besides the opportunity to use the ({}) construct, this would also prevent sending in stuff like strings/arrays/functions/etc. that could act like property holders.

Fine, except IE8 gives "[object Object]" for both null and undefined . Waaahhh...

Here's a rundown of what ({)}.toString.call(o); produces for various values of the parameter o:

IE9+, FF, Chrome, Opera IE8-
void 0 [object Undefined] [object Object]
null [object Null] [object Object]
{} [object Object]
[] [object Array]
/foo/ [object RegExp]
new Date [object Date]
"foo" [object String]
true [object Boolean]
false [object Boolean]
function() {} [object Function]
NaN [object Number]
1 [object Number]
new Error("foo") [object Error]

This “ class” -checking technique is generally quite useful, since it works with the language's underlying type for the value. It also works across frames and such, unlike instanceof . Just beware of the described behaviour regarding null and undefined in IE8-.

More reading in this old post (don' t skip the comments): http://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/