Skip to content

Instantly share code, notes, and snippets.

@WebReflection
Last active February 15, 2016 16:12
Show Gist options
  • Save WebReflection/6323064 to your computer and use it in GitHub Desktop.
Save WebReflection/6323064 to your computer and use it in GitHub Desktop.
An incrementally improved approach to a common JavaScript function/utility widely adopted all over. Returns the lowercase type or [[Class]] of a generic variable.
var typeOf = (function(Object, RegExp){
// WTFPL License - http://en.wikipedia.org/wiki/WTFPL
// thanks to @jdalton and @ljharb
var toString = Object.prototype.toString,
cache = (Object.create || Object)(null);
return function typeOf(Unknown) {
var asString = typeof Unknown;
return asString == 'object' ? (
Unknown === null ? 'null' : (
cache[asString = toString.call(Unknown)] || (
cache[asString] = asString
.slice(asString.indexOf(' ') + 1, -1)
.toLowerCase()
)
)
) : asString;
};
}(Object, RegExp));
@WebReflection
Copy link
Author

jsPerf comparison here plus a mandatory thanks to @jdalton for ints and tips

@WebReflection
Copy link
Author

the maximum amount of retained data in terms of strings and respective bytes is:

(Object.getOwnPropertyNames(this).filter(
  function(s){
    return  typeof this[s] == 'function' &&
            s[0] == s[0].toUpperCase() &&
            !/_/.test(s);
  },
  this
).map(
  function (s) {
    // toLowerCase() not needed
    return '[object ' + s + ']' + s.toLowerCase();
  }
).join('').length * 2 / 1024).toFixed(2) + 'KB';

Right now the amount in nodejs is 1.42KB and that's the worst case scenario assuming every single available instance of each type is passed to this function.

@rauschma
Copy link

This looks wrong: RegExp.lastMatch.toLowerCase(). Not part of ES5.

@WebReflection
Copy link
Author

nothing is wrong ;-) typeOf([]) is the string 'array' indeed, as example. RegExp.lastMatch is universally available since ever and it will be there for backward compatibility.

@mathiasbynens
Copy link

FWIW, RegExp.lastMatch has been in http://javascript.spec.whatwg.org/#regexp.lastmatch as a TODO item since its inception. Still needs to be specced, though.

@WebReflection
Copy link
Author

What's Special About This Code

  • it does not require pre memory allocation as a statically pre-filled map/object would do
  • it is incrementally optimized and compatible with every new native type that will be passed to the function (int32array, htmlcanvaselement, any other available type)
  • it is compatible with every JS environment being string representation agnostic and filled on demand using those representations ([array Array] or [JavaPackage nu.validator] cases )
  • it has ~zero runtime impact avoiding dynamic pre-filling of any native type

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment