JavaScript: an acceptable use of double-equals? Just.

When I first started learning and writing JavaScript, the recommendation I came across again and again was that the equality operator, ==, or “double-equals” was the devil incarnate. You should always use the identity operator, ===, or “triple-equals” because then you won’t have to battle weird type coercion bugs (and remember it’s not necessarily the time you write the original code that you’ll get tripped up, it’s the time you maintain it for the nth time).

Upside Downphoto © 2008 Nick Farr | more info (via: Wylio)So, imagine my surprise when reading the jQuery library code, I came across several uses of double-equals. What? Have Resig and the gang lost it?

Further investigation showed me the pattern they were using. In all cases, when double equals is used, the comparison is checking against null:

if (someObj == null) {
  // do something

OK, so is comparing against null somehow special? Time to refer to the language specification.

Section 11.9.3 of the 5th Edition gives the long-winded answer as a descriptive flowchart. In essence, the rules for when one side is null are as follows:

Note that this is more restrictive than just writing:

if (!someObj) {
  // do something

since this also allows the other four falsy values (false, 0, NaN, "") to pass through.

And it’s also simpler than writing:

if ((someObj === undefined) || (someObj === null))  {
  // do something

which is what it means precisely.

But, man, reading code that uses this construction brings me up short every time. It just seems to be a violation of best practices.

Album cover for HearsayNow playing:
O'Neal, Alexander - Criticize
(from Hearsay)

Loading similar posts...   Loading links to posts on similar topics...

7 Responses

#1 ELijah Manor said...
30-Jun-11 8:57 AM

That technique only with null has become common enough to get an "eqnull" flag option in JSHint to make that an acceptable construction.

I typically always use === or !== but in some cases I'll use == null or != null for the reasons you've mentioned above

julian m bucknall avatar
#2 julian m bucknall said...
30-Jun-11 9:41 AM

Elijah: Thanks for the JSHint clarification. It was not something I knew, but then again I'm still kickin' it old school by using JSLint. :) Maybe the differences between the two lints is the topic for another post.

Cheers, Julian

#3 mario said...
01-Jul-11 3:41 PM

Interesting. -- But btw, your SO user profile image breaks the /xhtml+xml; gave me an XML parser fail.

julian m bucknall avatar
#4 julian m bucknall said...
02-Jul-11 7:23 AM

Mario: Nice catch. I hadn't run the validator since adding the StackOverflow flair.

Turned out to have two issues: first the site's internal editor decided to replace & with & for editing and didn't change it back, and then the supplied flair code didn't properly terminate the element.

To which all I can say is a web site is never finished and is never perfect...

Cheers, Julian

#5 thattommyhall said...
22-Jan-13 11:41 AM

Not super critical but 'since this also allows the other four falsy values (false, 0, NaN, "") to pass through.' is not true unless you did

if !(someObj) {

  // do something

#6 thattommyhall said...
22-Jan-13 11:51 AM

oops, I mean

if (!someObj) {

  // do something

julian m bucknall avatar
#7 julian m bucknall said...
22-Jan-13 12:47 PM

Tommy: Damn. You are absolutely right, there should be a NOT operator there. Funny how we all just saw what we wanted to (expected to?) see rather than what was actually there. #facepalm

Since I have now changed this post so this code is accurate, here's what the second code snippet looked like:

if (someObj) {
  // do something

Cheers, Julian

Leave a response

Note: some MarkDown is allowed, but HTML is not. Expand to show what's available.

  •  Emphasize with italics: surround word with underscores _emphasis_
  •  Emphasize strongly: surround word with double-asterisks **strong**
  •  Link: surround text with square brackets, url with parentheses [text](url)
  •  Inline code: surround text with backticks `IEnumerable`
  •  Unordered list: start each line with an asterisk, space * an item
  •  Ordered list: start each line with a digit, period, space 1. an item
  •  Insert code block: start each line with four spaces
  •  Insert blockquote: start each line with right-angle-bracket, space > Now is the time...
Preview of response