[Laszlo-dev] One of the many reasons you should use === when you mean it

P T Withington ptw at pobox.com
Sat May 2 16:05:31 PDT 2009


So I'm profiling along, and I find an anonymous function that is being  
called a number of times.  It doesn't cost a lot, but I'm curious why  
it is anonymous.  It's not really anonymous, because our compiler  
assigns a debugging name to anonymous functions that you can use to  
find them in the source.  Here's the anonymous function:

>   static var _ignoreAttribute = {toString: function () {
>       return '_ignoreAttribute'}};

_ignoreAttribute is just a unique sentinel object that we use as a way  
to indicate that an attribute has already been processed, deep in the  
inner workings of LZX.  Someone (probably me) graciously gave it a  
`toString` method, so that when you are debugging and trip across it,  
you will realize that it is not just any old empty object.

But I'm not debugging.  I'm profiling.  I'm not calling  
`_ignoreAttribute.toString()`.  It's nowhere in the source code that I  
can see.  What is going on?  Well, here's a problem:

>     if (null != this.datapath && dp != LzNode._ignoreAttribute) {
>       this.datapath.setXPath(dp);
>     } else {

Can you spot it?  When `dp != LzNode._ignoreAttribute` runs, `dp` is  
normally a string, and read the fine print for how equality is  
computed in Javascript (from p. 64 of "ECMAScript Language  
Specification   Edition 3"):

> 1. If Type(x) is different from Type(y), go to step 14.
> [...]
> 20. If Type(x) is either String or Number and Type(y) is Object,
> return the result of the comparison x == ToPrimitive(y).

Well, I won't bore you with more gory details, but the bottom line is,  
every time we compare `_ignoreAttribute` to a String, the runtime has  
to call its `toString` method to see if it is "equal".

The storal of the morey is, when you want to compare for "identity",  
use the "strict equals operator" (`===` or `!==`), not the "equals  
operator".  [For my money, the former should have just been called the  
"identity" operator, but unfortunately it isn't quite.  There are some  
odd edge cases that make it not a _true_ identity operator.]


More information about the Laszlo-dev mailing list