Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
/*
* Sugar for type detection working across frames and browsers ;)
*
* Detected types
*
* 'arguments', 'array', 'boolean', 'date', 'document', 'element', 'error', 'fragment',
* 'function', 'nodelist', 'null', 'number', 'object', 'regexp', 'string', 'textnode',
* 'undefined', 'window'
*
* Copyright (c) 2009 Daniel Steigerwald (http://daniel.steigerwald.cz), Mit Style License
*/
var $type = (function() {
var toString = Object.prototype.toString,
toStrings = {},
nodeTypes = { 1: 'element', 3: 'textnode', 9: 'document', 11: 'fragment' },
types = 'Arguments Array Boolean Date Document Element Error Fragment Function NodeList Null Number Object RegExp String TextNode Undefined Window'.split(' ');
for (var i = types.length; i--; ) {
var type = types[i], constructor = window[type];
if (constructor) {
try { toStrings[toString.call(new constructor)] = type.toLowerCase(); }
catch (e) { }
}
}
return function(item) {
return item == null && (item === undefined ? 'undefined' : 'null') ||
item.nodeType && nodeTypes[item.nodeType] ||
typeof item.length == 'number' && (
item.callee && 'arguments' ||
item.alert && 'window' ||
item.item && 'nodelist') ||
toStrings[toString.call(item)];
};
})();
@rauschma

This comment has been minimized.

Copy link

rauschma commented Nov 8, 2011

If I may, a few comments:

  • If this code is supposed to run on Node.js, you can’t use window.
  • I like the way you look up the builtin types (comparing objects via === would be more elegant, but slower, because you would have to iterate through all of them).
  • I would add an additional case to support additional (custom) constructors.

I don’t like replacing if with || and && (I find the result hard to understand). How about the following rewrite?

function(item) {
    if (item === null) return "null";
    if (item === undefined) return "undefined";
    if (item.nodeType) return nodeTypes[item.nodeType];
    if (typeof item.length === 'number') {
        if (item.callee) return "arguments";
        if (item.alert) return "window";
        if (item.item) return "nodelist";
    }
    return toStrings[toString.call(item)];
}
@steida

This comment has been minimized.

Copy link
Owner Author

steida commented Sep 17, 2012

Thank you for quick review. The code is very very old, from times when NodeJS didn't exists. I do not use it anymore, because https://github.com/Steida/este. Google Closure has own type detection, handling edge cases better http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/base.js?r=2#536.

Ad syntax: How I would write it today :-)

(item) ->
  return 'null' if item == null
  return 'undefined' if item == 'undefined'
  return nodeTypes[item.nodeType] if item.nodeType?
  if typeof item.length == 'number'
    return 'arguments' if item.callee
    return 'window' if item.alert
    return 'nodelist' if item.item
  toStrings[toString.call item]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.