JScript Equality Operators, plus More On Mad Crushes

First, the technical stuff. Here's a recent question I received about missing data in JScript.

I’ve seen it stated that in order to determine if a variable is undefined, you have to useif("undefined" == typeof(x))I attended a presentation on JScript today where the presenter usedif(undefined == x)When I asked about that, he stated that it works and he is not aware of any problems with it. Is he correct?

I discussed related issues earlier (here and here and here), but I figure that this is another opportunity for clarification.

There are three statements made.

1) In order to determine if a variable is undefined, you have to use if("undefined" == typeof(x))2) if(undefined == x) works 3) Mr. Presenter Guy is not aware of any problems with (2).

The first statement is demonstrably false because of that "have to" in there. The typeof trick works, but "have to" implies incorrectly that it is the only thing that works. This works just as well: if (x === undefined) (Note that triple equals in there. More on that below.)

The second statement is also demonstrably false, because it has "false positives". Yes, this detects when a value is undefined, but…

var x = null;print(x == undefined);

will evaluate as true, even though x is clearly defined! undefined and null compare as equal to each other; this does not determine if a variable is undefined, it determines if a variable is undefined or is defined as a value which the comparison operator considers as equal to undefined.

The third statement was true; Mr. Presenter Guy was probably not aware of any problems. I asked the original questioner to point out to Mr. Presenter Guy that the == operator gives false positives, so hopefully the third statement is also now false.

What the heck is up with the === operator? Here's the thing: the == operator is very lenient when comparing data of different types.

print("1" == 1); // true

Which is often very useful. But then one day (April 23rd, 1997, if you care) we added the switch statement to JScript and this question immediate arose: what the heck does this do?

because then this would print "string" when clearly the other case is by far the better match.

The switch statement requires that not only must the case and the argument compare as equal, but they must also be of the same type.

Given that, it would then seem really weird if you could construct a switch statement with these comparison semantics but could not construct the equivalent if statement. Therefore we added the === operator, which has the same semantics as the comparator used in the switch statement.

This now explains why this works for undefined variables. The === operator checks to see whether the arguments are of the same type; since there is only one member of the undefined type, there can be no false positives.

****************************

In other news, I've managed to avoid the terrible fate that befalls boys who will not propose marriage. No one will be exiling me to a desert island surrounded by sharp rocks and dropping hate-mail valentine cards from helicopters! My erstwhile lovely girlfriend Leah is now my charming fiancée Leah, and I couldn't be more pleased. The plan so far is to get married next summer on the beaver-shark-infested shores of romantic Lake Huron, spend a week or so in romantic Holland, and then throw a huge yet elegant dance party back in romantic Seattle.

(UPDATE: Leah has just sent me an email saying that if anyone does exile me to a desert island, she will rescue me and then bake me that cake. That's good to know.)

Congratulations! I hope to avoid that terrible fate myself ... but unless all the women I know are being insanely subtle (though after reading some of the mad crush advice, that's not out of the realm of possibility), I'm not in the "at risk" demographic.

Curiosity now begs the question ... "What horrible fate befalls boys that propose marriage to the girls that don't want it?" Hopefully it's something nicer than being beaten up and exiled to a desert island.

Hey, Mazel Tov Eric! May you guys have a long and wonderful life together.

Shike Maffer

26 Jul 2004 12:57 PM

Congrats Eric! Hope you and Leah will be very happy for years to come.

Thanks for the insight into the === operator. I had a student ask about this, in the light of the fact that JScript is not typed, how can you compare object types? My response was for him sit down and get back to work on today's lesson :-) or something equally as non-educating. I have sent him an email (he's since graduated) correcting my error. Thanks again!

Dan Shappir

26 Jul 2004 1:46 PM

Congratulations Eric! As a ten year veteran I can honestly tell marriage is a good thing (my wife has yet to rescue me off a desert island, but she has baked me a cake).

I'm not following you. Step 3 of GetBase can only be executed if step 1 returns a reference. All references have a base object. There's nothing in here that can produce an exception.

Are you perhaps thinking of Step 3 of GetValue? Sure, that can throw an exception, but step 3 of GetBase ensures that GetValue is never called with a null reference.

Steve

26 Jul 2004 1:57 PM

Congrats! You never fully realize the "can't live with them..." saying until you're married. I wouldn't trade it for the world and I'm sure you'll feel the same way about yours.

Nicholas Allen

26 Jul 2004 6:33 PM

Hey, congratulations on making the big move!

As an interesting Internet confluence, today we got a bug report from someone that "1" != 1 when they specified JavaScript version 1.2.

The original JavaScript had type insensitive equality and the final ECMA standard v1 had type insensitive equality. However, Navigator 4 was based on a draft standard (along with a raft of Netscape extensions) and shipped with a type sensitive == and !=. This was JavaScript version 1.2 (1.0 and 1.1 correspond to the previous Navigator 2 and 3 releases). It lasted from late '96 more than a year until Navigator 4.5 was released.

The === and !== were added in JavaScript 1.3 and regular equality was changed back to the type insensitive version. Unless of course, you specifically ask for version 1.2.

Re: JavaScript 1.2 -- indeed! Though I had forgotten the exact details, I certainly recall my colleagues who were attending the committee meetings in 1997 describing a certain amount of kerfuffle around this misfeature of 1.2. What a mess.

Heh. That's sort of the point. What I want to ask is "does document.getElementbyId exist, and is it the DOM function that I'm expecting it to be?" Since, obviously, I can't ask that specifically, which of your three questions is least likely to give me an answer that differs from the answer to my ideal question? There isn't a clear answer to this, naturally; I'm more curious what you would use in that situation.

Oh, I wasn't intending to pose a security question, really. At the moment, before I use any DOM code like document.getElementById() in a page, I bracket said code with if (document.getElementById). My question was more, "given the choice, which would you do?"