Tales from the Evil Empire

Bertrand Le Roy's blog

News


Bertrand Le Roy

BoudinFatal's Gamercard

Tales from the Evil Empire - Blogged

Blogs I read

My other stuff

Archives

Define undefined

We already knew that JavaScript had some issues with semantics. Here's another funny one. Guess what this code does:

var a; alert(a === undefined);
alert(typeof(a));
alert(typeof(undefined));
alert(typeof(a) === 'undefined');
undefined = {};
alert(a === undefined);
alert(typeof(a));
alert(typeof(undefined));
alert(typeof(a) === 'undefined');
true = false;

You'll get the following values in the alerts: true, "undefined", "undefined", true, false, "undefined", "object", true.

For some strange reason, JavaScript enables you to redefine "undefined". Just in case you're wondering, undefined is not just some variable that happens to be undefined, it is an official primitive value (but not a keyword). If you declare a variable but don't set its value, it gets that undefined value. Now after our silly redefinition of the undefined, typeof(a) is "undefined" but typeof(undefined) is "object", which more or less means that undefined is not undefined. Nice.

So why would anyone in their right minds define undefined? I don't have the beginning of a clue, but that means that strict comparison to undefined is broken (as the code above demonstrates) and that typeof(a) === 'undefined' should be used instead (at least in principle).

This is so much fun! So any other important primitive values we can overwrite just to see what happens? Sure, let's try this:

alert(isNaN(Number.NaN));
Number.NaN = 1;
alert(Number.NaN);
alert(isNaN(Number.NaN));

Curiously enough, JavaScript seems to let you define NaN without throwing, but it actually doesn't do it: the alerts here show true, NaN and true.

From what I can tell, this redefinition of a primitive value seems to be "valid" only for undefined. Null can't be assigned to, neither can true, false or numbers. Too bad, how fun would that have been (in true daily WTF style):

var reallyTrue = true;
true = false;
false = reallyTrue;
if (true) {
  alert("That's it, I'm officially confused");
}
else {
  alert("Errr?!");
}

Thanks to Mike Harder for discovering that gem.

Comments

InfinitiesLoop said:

It's almost too bad you can't reassign other primitives. It would open the door to a whole new world of client-side obfuscation! :)
# August 6, 2006 2:04 PM

steve johnson said:

Here's one more, when you know the variable

exists, but the value is undefined.

if (undefined != var)

# September 20, 2007 2:33 PM