typeOf() - A Way To Check Data Types.
In my previous blog post I talked about boolean tests. Although JavaScript is a loosely typed language, wouldn't it be nice to have a straightforward way to check data types? I thought about that and started experimenting with tests. The result is a function that does that. No more wondering what your datatype is and worrying if you can determine it safely before performing an operation on it.
Here's the skinny on typeOf(). You pass it data and it gives you back a string indicating its type. You need to pay attention to that string because looks are everything. What do I mean by that? Strings beginning with an uppercase letter are objects. Strings beginning with a lowercase letter are literals. And, as a extra bonus, this function returns numbers as type int or float for literals and Int and Float for objects.
While putting this function together I ran into one gatcha that really surprised me. Live and learn. JavaScript exposes no properties or methods to distinguish between array literals and array objects nor between object literals and object objects. It considers them exactly equal. At least in the case of object literals you need to be aware that they are not 100% equal to object objects because they have no prototype member. However, a newly created object object without any members defined also does not expose its prototype member, so there is no way to reliably distinguish these two.
Regardless of this, the typeOf() function does introduce the ability to test types in a reliable way for the data that can usually trip you up. Without any further delay, let me introduce typeOf(). (Audience applauds ecstatically)
/////////////////////////////////////////////////////////
//
// Method to test the type of data. It returns a string.
// If the data is a JavaScript primitive, it will return
// the string in lowercase. If the data is an object type,
// it returns a string with an uppercase initial letter.
// Array literals and object arrays are identified with
// and initial uppercase letter string, as are object literals
// and object objects. This is because JavaScript does not
// distinguish between the literal and object versions of
// these two datatypes.
//
/////////////////////////////////////////////////////////
function typeOf(value) {
// First check to see if the value is undefined.
if (value == undefined) {
return "undefined";
}
// Check for objects created with the "new" keyword.
if (value instanceof Object) {
// Check for a boolean object.
if (value instanceof Boolean) {
return "Boolean";
// Check for a number object.
} else if (value instanceof Number) {
// Test whether it's a float or int.
if (/\./.test(value)) {
return "Float";
} else {
return "Int";
}
// Check whether it's a string object.
} else if (value instanceof String) {
return "String";
// Check whether it's an array object/array literal.
} else if (value instanceof Array) {
return "Array";
// Check whether it's a date object.
} else if (value instanceof Date) {
return "Date";
// Check whether it's a function object.
} else if(value instanceof Function) {
return "Function";
// Check whether it's and object object/object literal.
} else if (value instanceof Object ) {
return "Object";
}
// If these tests failed, check to see if we're
// dealing with a literal.
} else if (typeof value) {
// Here we're testing for null. Get this,
// JavaScript returns it as an object!
// So first we check for object, then for value.
if (typeof value == "object") {
if (typeof value == "object" && !value) {
return "null";
}
// If the value wasn't null, check if it is a literal.
} else {
// Check for a boolean literal.
if (typeof value == "boolean") {
return "boolean";
// Check for a number literal.
} else if (typeof value == "number") {
// Check if the number literal is a float or int.
if (/\./.test(value)) {
return "float";
} else {
return "int";
}
// Check if it's a string literal.
} else if (typeof value == "string") {
return "string";
}
}
// If it slipped through all these tests,
// we're dealing with something undetectable.
// Therefore return nothing.
} else {
return false;
}
}
P.S. If you're going to use this, please namespace it to protect yourself from global pollution.
Here are some examples of results returned by typeOf():
var u; // Create an undefiend variable.
alert(typeOf(u)); // Returns "undefined."
var n = null;
alert(typeOf(n)); // Returns "null."
var i = 123;
alert(typeOf(i)); // Returns "int," which indicates a number literal integer.
var f = 12.3;
alert(typeOf(f)); // Returns "float," which indicates a number literal float.
var s = "text";
alert(typeOf(s)); // Returns "string," which indicates a string literal.
var a = [1, 2, 3];
alert(typeOf(a)); // Returns "Array." Does not indicate whether literal or object.
var o = { name : "John" };
alert(typeOf(o)); // Returns "Object." Does not indicate whether literal or object.
var B = new Boolean(true);
alert(typeOf(B)); // Returns "Boolean," which indicates a boolean object.
var I = new Number(123);
alert(typeOf(I)); // Returns "Int," which indicates a number object integer.
var F = new Number(12.3);
alert(typeOf(F)); // Returns "Float," which indicates a number object float.
var S = new String("text");
alert(typeOf(S)); // Returns "String," which indicates a string object.
var D = new Date();
alert(typeOf(D)); // Returns "Date," which indicates a date object.
var Func = new Function();
alert(typeOf(Func)); // Returns "Function," which indicates a function object.
var A = new Array(1, 2, 3);
alert(typeOf(A)); // Returns "Array." Does not indicate whether literal or object.
var O = new Object();
alert(typeOf(O)); // Returns "Object." Does not indicate whether literal or object.
And that's it. Not strict, strict typing, but better than nothing.