javascript: when to use typeof

It was ingrained in my brain to never use typeof. “JavaScript the good parts” even lists it in the section awful parts. So let’s first look at what typeof really does and why it’s considered evil.

What does typeof do?

typeof returns a string with the type (not the class) of an obj.

typeof 1         // => 'number'
typeof true      // => 'boolean'
typeof 'str'     // => 'string'
typeof undefined // => 'undefined'
typeof function () {} // => 'function'
typeof null      // => 'object'
typeof {}        // => 'object'
typeof []        // => 'object'
typeof /\w+/     // => 'object' or 'function'

The reason typeof is considered awful is that for Number/String objects typeof returns ‘object’ and not as we would expect ‘number’.

typeof new Number(1)    // => 'object'
typeof new String('f')  // => 'object'
typeof /a/              // => 'object' or 'function'

This makes typeof unsuitable for checking the type of an object. Instead many libraries agree upon one way of doing things. The typical implementation of isNumber() looks like that.

function isNumber(obj) {
  return == '[object Number]'

The beauty of this implementation is how clean and reliable it is, furthermore the same implementation can be used for all other types as well.

The reason this works is that call( 1 ) will coerce the given JavaScript primitive 1 to a Number type new Number(1). The following code snippet illustrates that process.

function foo() { console.log(typeof this) } 1 )
// 'object' (not 'number' as you might assume)

Unfortunately this process is also terribly slow.

Use typeof for performance

Performance is where typeof shines. Raw uncomprised speed. Let’s improve the ubiquitious isNumber method and make it run 50 times faster.

The main idea is to only call the expensive part if we really need to and exit early when we know it is a number primitive.

function isNumberFast(obj) {
  if (typeof obj == 'number') return true;
  return == '[object Number]'

isNumberFast is now blazingly fast when you pass it a number primitive. However it is still slow for other primitives such as string, boolean, undefined. We can improve on that by simply adding an additional check that returns quickly for any other primitive.

function isNumberFaster(obj) {
  if (typeof obj == 'number') return true;
  if (typeof obj != 'object') return false;
  return == '[object Number]'

See the benchmarks here:

Use typeof before checking for properties

One more case where typeof can have a significant impact is when checking for properties.

function wrap(obj) {
  if (obj && obj._wrapped) return obj;
  return {_wrapped: obj};

The wrap method checks if the obj has a property _wrapped and if so returns early. The if clause first checks if obj is falsey and if it contains a _wrapped property. When passing a primitive it has to be typecasted to its corresponding class first to check for the property. This costly typecast can easily be avoided.

function wrap(obj) {
  if (obj && typeof obj == 'object' && obj._wrapped) return obj;
  return {_wrapped: obj};

Another low-hanging fruit to improve performance by a magnitude. Check benchmarks:

Do not overuse these techniques

Do not use these techniques everywhere. Restrict yourself to methods that are heavily used internally. There is a tradeoff between code readability and performance. RubyJS uses typeof checks for the R() method and to typecast method arguments (or rather to avoid unnecessary typecast).

Further reading

© 2012-13 FundExplorer GmbH Back to Top