Mikol Graves, recently commented on my Type Detection article showing a novel way to do type detection. Here is his code snippet:
function isTYPE(o) { return (o != null && typeof o ===object&& o.constructor.toString() === TYPE.toString()); }
For each Object type that you care about, for example: Date, Array, Class, to name a few. You simply replace "TYPE" with the appropriate Object name. These examples would produce functions like:
function isArray(o) { return (o != null && typeof o ===object&& o.constructor.toString() === Array.toString()); } function isDate(o) { return (o != null && typeof o ===object&& o.constructor.toString() === Date.toString()); } function isClass(o) { return (o != null && typeof o ===object&& o.constructor.toString() === Class.toString()); }
This is nice, because it gives you a way of detecting all kinds of Meta Object types that you might care about. However, you end up using the same code over and over again. Therefore, I took some time and looked around the different toolkits for various other ways that type detection was being done. I found a snippet of code that I really liked in mootools.v1.11. Here is the code:
/* Function: $defined Returns true if the passed in value/object is defined, that means is not null or undefined. Arguments: obj - object to inspect */ function $defined(obj){ return (obj != undefined); }; /* Function: $type Returns the type of object that matches the element passed in. Arguments: obj - the object to inspect. Example: >var myString =hello; >$type(myString); //returns "string" Returns:element- if obj is a DOM element nodetextnode- if obj is a DOM text nodewhitespace- if obj is a DOM whitespace nodearguments- if obj is an arguments objectobject- if obj is an objectstring- if obj is a stringnumber- if obj is a numberboolean- if obj is a booleanfunction- if obj is a functionregexp- if obj is a regular expressionclass- if obj is a Class. (created with new Class, or the extend of another class).collection- if obj is a native htmlelements collection, such as childNodes, getElementsByTagName .. etc. false - (boolean) if the object is not defined or none of the above. */ function $type(obj){ if (!$defined(obj)) return false; if (obj.htmlElement) returnelement; var type = typeof obj; if (type ==object&& obj.nodeName){ switch(obj.nodeType){ case 1: returnelement; case 3: return (/\S/).test(obj.nodeValue) ?textnode:whitespace; } } if (type ==object|| type ==function){ switch(obj.constructor){ case Array: returnarray; case RegExp: returnregexp; case Class: returnclass; } if (typeof obj.length ==number){ if (obj.item) returncollection; if (obj.callee) returnarguments; } } return type; };
This was a good foundation for an improvement upon my type detection Functions. The $type Function can detect nearly all of my "isType" Functions straight away and has the power to detect some other important types, such as: arguments, textnode, element, collection, and more. So far, I have only added Date in addition to the types already defined and created an additional Function "isType" which can be used to test the object against a desired type.
We lose, "isAlien" Function and whether the number is finite. However, I never use these anymore, so I do not really need them. So far I believe the benefit of using these Functions will out-weight the loss. Although, I have also found these issues: testing for whitespace
does not work with IE because IE ignores whitespaces when parsing the DOM; in Opera testing for arguments
will return array
, because Arguments constructor is Array (go figure). Otherwise, it has worked flawlessly and these issues can be worked around. I put together a test page, to verify the results of the isType Function and checked variations on the most common browsers.
You can download my Type Detection JavaScript file.