dclowd9901
dclowd9901

Reputation: 6826

What does undefined === undefined compare?

After reading through Lodash's code a bit and learning that it uses typeof comparisons more often than not (in its suite of _.is* tools), I ran some tests to confirm that it is faster, which it is, in fact (if marginally).

Discussing my confusion with a fellow developer, he pointed out that in case 1:

var a;

return a === undefined;

Two objects undergo comparison, whereas in case 2 (the faster case):

var a;

return typeof a === 'undefined';

is a far more simple and flat string compare.

I was always of the thought that undefined inhabited a static place in memory, and all triple equals was doing was comparing that reference. Who's correct (if either)?

JSPerf Test: http://jsperf.com/testing-for-undefined-lodash

Upvotes: 2

Views: 359

Answers (2)

user2864740
user2864740

Reputation: 61865

In this case (with var a in scope), both of the two posted pieces of code have identical semantics as x === undefined is only true when x is undefined and typeof x will only returned "undefined" when x is undefined (or not resolved in the execution context).

That out of the way, we end up with:

undefined === undefined

vs.

"undefined" === "undefined"

So, even in a naive implementation case the "difference" between the two is SameObject(a,b) vs StringEquals(a,b) as per the rules for Strict Equality Comparison.

But modern implementations of JavaScript are quite competitive and, as can be seen, are very well optimized for this case. I don't know of the exact implementation details, but there are at least two different techniques that could allow the performance (in FF/Chrome/Webkit) to be the same for both cases:

  1. ECMAScript implementations may intern strings, such that there is only one "undefined" string. This would make the StringEquals(a,b) effectively the same as SameObject(a,b) which would end up amounting to a "pointer comparison" in the implementation - this alone could explain why the performance is the same.

  2. Additionally, because typeof x === "undefined" is a common idiom, it could be translated during the parsing to end up in a special call that performs the same, say TypeOfUndefined(x). That is, the implementation could bypass the === (and StringEquals) entirely if it so chose.

IE comes out as a the "clear loser" and seems to be missing an applicable optimization here.


The implementation of the undefined value is outside the scope of ECMAScript; there are no mandates that it must be a single value/object in the implementation.

In practice, however, undefined (and other special values like null) is most likely implemented as either a singleton (e.g. "one object in memory") or as an immediate value or value flag (such that there is actually no undefined object).

Upvotes: 3

freakish
freakish

Reputation: 56467

According to EcmaScript (see http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf ) if both expressions are strings (typeof returns a string) it perfroms a string comparison (char by char), otherwise it just compares references (in case when one of the sides is undefined). There is no way that string comparison would be more efficient then simple two numbers (i.e. addresses in memory) comparison. However it is possible that it is highly optimized (browsers do not follow EcmaScript in 100%) so it's really hard to say.

Proper benchmark:

http://jsperf.com/undefined-comparison-reference-vs-string

Note that in your test the initial value of a is undefined (may or may not matter, it seems that it does).

Conclusion: always use

return a === undefined;

It definitely won't be slower and it might be faster. Besides it seems more natural to compare something to a special undefined object rather then to a string.

Upvotes: 3

Related Questions