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).
photo © 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:
null
, return true
;undefined
and the other is null
, return true
;false
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.
Now playing:
O'Neal, Alexander - Criticize
(from Hearsay)
7 Responses
#1 ELijah Manor said...
30-Jun-11 8:57 AMThat technique only with null has become common enough to get an "eqnull" flag option in JSHint http://jshint.com 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
#2 julian m bucknall said...
30-Jun-11 9:41 AMElijah: 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 PMInteresting. -- But btw, your SO user profile image breaks the /xhtml+xml; gave me an XML parser fail.
#4 julian m bucknall said...
02-Jul-11 7:23 AMMario: 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 AMNot super critical but 'since this also allows the other four falsy values (false, 0, NaN, "") to pass through.' is not true unless you did
#6 thattommyhall said...
22-Jan-13 11:51 AMoops, I mean
#7 julian m bucknall said...
22-Jan-13 12:47 PMTommy: 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:
Cheers, Julian
Leave a response
Note: some MarkDown is allowed, but HTML is not. Expand to show what's available.
_emphasis_
**strong**
[text](url)
`IEnumerable`
* an item
1. an item
> Now is the time...
Preview of response